When I should use the user model from Django? - python

I created this class Person, but looking at the Django User model they seem to be very similar.
In this case, should I be using it ? Or should I keep with my own model ?
My major concern is that, I don't want to my users login into localhost:8000/admin page and start to mess with my system and other users data.
class Person(models.Model):
full_name = CharField(max_length=255)
address = CharField(max_length=255)
city = CharField(max_length=255)
country = CharField(max_length=2, choices=CountryChoices, default='')
gender = CharField(max_length=1, choices=GenderChoices, default='')
email = EmailField()
password = CharField(max_length=255)
started = DateTimeField(auto_now_add=True, auto_now=False)
updated = DateTimeField(auto_now_add=False, auto_now=True)
#how it's show in admin
def __unicode__(self):
return smart_unicode(self.full_name + ' (' + self.email + ')')

You should not create this model. Apart from any considerations of efficiency, it looks as though you are storing passwords in clear text, which is an absolute no.
Instead, extend AbstractBaseUser and set AUTH_USER_MODEL to point to that model. If you define an is_staff boolean field, your users will not be permitted to log into the admin site as long as they have that field set to False.

If you're not looking to give you users access to the admin, there's nothing wrong with using the model that you've included here.
If you wanted to use the auth User model, you certainly could. If you want to add the User model to your model later on, you could tie them together with a ForeignKey.

this is wrong. some of this field are in User model. and it is better to use User model and define aditional field in your model. take a look at Storing additional information about users.
Also you can develope your own login system like this.

Related

Django rest framework create password for custom user model

Actually I'm creating an employee management system project using django rest api.
Now i have created my own custom models like shown below, i want to create the register employee with the below models. But how can i set the password field for login, since I haven't included in my fields. I've attached my models and serializer. Please do help for me. I'm beginner
Class Employee (models.Model):
name = models.CharField(max_length=50, unique=True, verbose_name='None')
email = models.EmailField(verbose_name='Email')
department = models.CharField(max_length=30, unique=False, verbose_name='Departamento')
(And many more details like personal email,contact, and many)
# Function used to display the employee's name in the admin page
def __str__(self):
return self.name
My serializer class is
class Employee DetailsSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
Fields = [__all__]
My views be like, i want to create register view, since i dont have password in my model, how to create password field to my above shown register field,
Whatever maybe my register field should contain all those above details. I'm scratching my head here.please someone help
Yes, you can add a password field in your Employee model but you are requested not to do it because Django already provided this type of facility. Just you have to know How to use it. Try to extend the existing User model from django.contrib.auth.models.User.Let's organize your Employee model.
from django.contrib.auth.models import User
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
#name = models.CharField(max_length=50, unique=True,
verbose_name='None')
#email = models.EmailField(verbose_name='Email')
department = models.CharField(max_length=30, unique=False,
verbose_name='Departamento')
#property
def name(self):
return "{0} {1}".format(self.user.first_name,
self.user.last_name)
No need to add an email field because this field already exists in the User model and the name field can be a property that retrieves data from the user model and the rest of the code will be unchanged. So you are concerned about the password field and it also exists in the User model.
Please check out this repo and it might help you.

It is impossible to add a non-nullable field Error when extending Abstract User

I want to extend the Base Abstract User Model and this is the extended model:
class Student(AbstractUser):
birth = models.DateField(default=datetime.date.today)
street = models.CharField(max_length=25)
street_number = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(99)])
city = models.CharField(max_length=20)
province = models.CharField(max_length=20)
code = models.IntegerField(validators=[MinValueValidator(0, MaxValueValidator(9999))])
address = str(street) + str(street_number) + str(city) + str(code) + str(province)
But I get this message popup:
It is impossible to add a non-nullable field 'password' to student without specifying a default. This is because the database needs something to populate existing rows.
However I haven't added a new password field and all the existing password fields (for the superuser) already have a value. What should I do?
When I add a default value and try to migrate it, it complains that there is no such table as 'mainApp_student'.
You don't want to do that. You want a User model (you already have one that Django provides, no need to extend it for now), and a Student model that has a OneToOne relationship with the User model.
Conceptually:
User: models a user of your application and its authentication and permissions
Student: the representation of a person attending classes, with a name, a birthday etc..., also has a user to access your application which is unique to them.
In code:
from django.db import models
from django.contrib.auth.models import User
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE))
# ... other fields: birth address etc...
This page of the docs explains it well, especially the Employee example given:
If you wish to store information related to User, you can use a OneToOneField to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.

Can I change to a CustomUser model after the initial migration? Or I should've done it at the start of the project?

I'm trying to add custom user model mid project, and I might remember reading somewhere that you can't do that or that it isn't easy to do so, is that true? What can I do now?
The best way to proceed with this is to make another model which uses an OneToOneField to the user model. For example I am making this model to add fields like profile_pic, Your_website.
models.py
class UserProfileInfo(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
Your_website = models.URLField(blank = True)
profile_pic = models.ImageField(upload_to="profile_pics", blank = True)
def __str__(self):
return self.user.username
On your next migration it will ask you to provide a default for the user field so remember to do so.
By this method you can create a custom user model with the existing user model.

How do I perform string actions on some CharField() or TextField right there in the model definition?

I am working on one of my first Django projects and on one of the models, I needed a field that returns a list that I can loop through and use in my templates. I have been trying to make it happen right there in models.py because I learned from the tutorials that it is best to perform all data manipulation or logic in the models file and nothing of such should be done in the templates as the template is just for rendering already parsed data.
I tried:
class Profile():
'''More user information.'''
user = models.ForeignKey(User, on_delete=models.CASCADE)
user.first_name = models.CharField(max_length=25)
user.last_name = models.CharField(max_length=25)
interests = models.CharField(max_length=200)
user.interests = [interest.strip() for interest in interests.split(',')]
In the code snippet above, I tried splitting comma separated values input by the user to try and make a list of it but I got the error:AttributeError: 'TextField' object has no attribute 'split'. Since the models.Charfield() and models.TextField() don't return a string, how do I go about this?
I use the sqlite db on my local.
The user model already has first_name and last_name so you can remove
If you want your user model to have the property interest you need to user custom user model
For performing an action on a field before saving it example you splitting the interests you can override the save method for the model

Creating a new instance of a Custom User Model in Django

I have a model which is an extension of a User model in Django 1.8. I am also connecting to a MySQL database for this.
class LibraryUser(models.Model):
user_id = models.OneToOneField(User)
is_catalogue_subscriber = models.BooleanField(default=True)
is_research_subscriber = models.BooleanField(default=True)
library_membership_number = models.CharField(max_length=64)
The reason why I extended the User model, of course is to use the authentication framework.
So now, I want to create a new LibraryUser using the library_membership_number as the login username. How should I do so? Do I create the User first then reference the LibraryUser?
ie given some_ variables either received by a POST or by migration of users to the new table
u = User.objects.create_user(email=some_email, password=some_password)
lu = LibraryUser(library_membership_number, user_id = u.id)
lu.save()
Or is there a correct way to do this? Tried finding online but can't find something to particularly address this problem.
You should assign value to the specify fields as the following:
lu = LibraryUser(library_membership_number= '...', user_id = user)
lu.save()
library_membership_number
You can't just assign a variable to library_membership_number. model is a object containing the fields. You should appoint the field and assign it: library_membership_number= '...', or model can't parse which field you will store.
user_id
It has defined foreignkey in advance. It can accept another model object to store: user_id = user. Don't call attribute of the user to store in LibraryUser.

Categories