I have a question regarding the custom user model in Django 1.5
So right now the default user model looks just fine to me, I just need to add a few other variables such as gender,location and birthday so that users can fill up those variables after they have successfully registered and activated their account.
So, what is the best way to implement this scenario?
Do I have to create a new app called Profile and inherit AbstractBaseUser? and add my custom variable to models.py? Any good example for me to follow?
thank you in advance
You want to extend your user model to the AbstractUser and add your additional fields. AbstractUser inherits all of the standard user profile fields, whereas AbstractBaseUser starts you from scratch without any of those fields.
It's hard to define best practices this close to the release, but it seems that unless you need to drastically redefine the User model, then you should use AbstractUser where possible.
Here are the docs for extending the User model using AbstractUser
Your models.py would then look something like this:
class MyUser(AbstractUser):
gender = models.DateField()
location = models.CharField()
birthday = models.CharField()
MyUser will then have the standard email, password, username, etc fields that come with the User model, and your three additional fields above.
Then you need to add the AUTH_USER_MODEL to your settings.py:
AUTH_USER_MODEL = 'myapp.MyUser'
Related
I've written my first application Django 2.0.
Everything is working fine and the application is almost ready when I realized to replace id primary key field from default integer type to UUID to make database entry more secure.
When I searched for this how to change id of user table to UUID I got many tutorials extending AbstractBaseUser.
Here is I have written own User model.
account/models.py
class User(AbstractBaseUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
But I'm confused more with examples on different sources.
Every example is adding few more fields in extended model like
first_name
last_name
is_staff
is_admin
active
and functions as
def get_fullname(self):
def get_shortname(self):
etc.
I think all these fields and functions are there by default in AUTH_USER_MODEL.
Does extending AbstractBaseUser overwrites AUTH_USER_MODEL and it is required to add all fields which is there by default?
also, I'm using settings.AUTH_USER_MODEL as foreign key in different models. Should It be replaced by account.User model?
I'm also using django-allauth plugin to enable login using the social network and use email only for authentication. Do I require to add email field in the extended model with unique=True?
Django AbstractBaseUser provides only following fields: password, last_login, is_active. So if you are using custom User model inherited from AbstractBaseUser you need to define all other fields such as email manually.
As another part of question just adding AUTH_USER_MODEL = 'users.User' to your settings.py file should make everything works without replace code in your project.
UPD
If you need field like first_name, last_name, etc. to be includet to the model you can use AbstractUser instead of AbstractBaseUser.
As the Django documentation indicates, it's difficult to extend the User table after-the-fact, and not recommended at all for apps. A better way is to create an auxiliary table which has a 1:1 relationship with the user-id. Leave Django's user-table alone and just use this other table to pony-up to it.
The "Django Annoying" project, at https://github.com/skorokithakis/django-annoying#autoonetoonefield, has some very useful "juice" to make this much easier: an AutoOneToOneField. Whereas Django's foreign-key field will throw an error if an record doesn't exist, this field will automagically create one on-the-fly, thereby side-stepping the entire issue. (The documentation page linked-to above shows exactly how this is done.)
Actually, I'm working on a project where I need to save some details like name, username, password, age, gender etc of every user.
In that website, any user can login to their account, edit information.
So should I use the default users model or create a new model
I suggest you subclass AbstractUser. This option is suitable if you're fine with Django's User fields, but need extra fields. Django documentation also recommends to do this anyway.
If you’re starting a new project, it’s highly recommended to set up a
custom user model, even if the default User model is sufficient for
you. This model behaves identically to the default user model, but
you’ll be able to customize it in the future if the need arises:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass or additional fields here ...
You also have to point to this model before creating or running any migration in the settings:
AUTH_USER_MODEL = 'yourapp.User'
Default user model in Django save some limited fields about one user. fields are
first_name, last_name, email, password, groups, user_permissions, is_staff, is_active, is_superuser, last_login, date_joined
If you want to save other information of user like birthday, expertise, gender you have to write userprofile model which must be linked one to one with user.
Example:
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OnetoOneField(User)
birthday = models.DateTimeField(default=datetime.datetime.now)
skills = models.CharField(max_length=128)
Actually, If you want to create a custom user model for user, It's mentioned in the Django's Official documentation. For achieving that you have to first inherit your custom user model with AbstractUser class and then pointing that custom user in your settings file by mentioning
AUTH_USER_MODEL = 'mycustom_user_app.MyCustomUser'.
Now django internally knows which model is the User model for the project, and you can access all model managers(e.g. create_user, etc. ) for your custom user. In that way you can use the current models fields and also can add more fields into it. That's the legit way to go with and to customize your User Model as mentioned in the documentation
in django,i want to extend the auth_user model and adding the 2 fields.one is created_user which will display the date and time when user created something and other is modified_user which will display the date n time when modification is done..
is it possible by migration??
i ve tried dis code..
from django.contrib.auth.models import User, UserManager
class CustomUser(User):
created_user= models.DateTimeField("date and time when created")
modified_user=models.DateTimeField("date and time when modified")
objects= UserManager()
I suggest reading the documentation on creating your own custom user model.
In your particular case, the easiest thing would probably be to subclass AbstractUser and add your fields as above.
If you’re entirely happy with Django’s User model and you just want to add some additional profile information, you can simply subclass django.contrib.auth.models.AbstractUser and add your custom profile fields. This class provides the full implementation of the default User as an abstract model.
If I create a CustomUser model which inherits from django.contrib.auth.models.User, like so:
in models.py
class CustomUser(django.contrib.auth.models.User):
customfield = TextField()
...
Should I still be able to use
django.contrib.auth.{authenticate, login, logout} in the normal way? Do I have to make some additional configuration change? I know these methods only work on User objects, but technically my CustomUser is-a User.
Currently, authenticate(username=u, password=p) is always returning None, even with valid credentials.
Since Django 1.5 (officially but it doesn't worked for me) and "stable" in 1.6 there is a functionality to extend the User model in a clean way.
At first:
-> Take care that you load the User model only via:
from django.contrib.auth import get_user_model
User = get_user_model()
-> Once you have built the database theres no easy way to change the User model. The database relations will break and Django / South isn't able to fix it.
-> third party modules have to be compatible with that new layout and refer in it's models to "get_user_model()", too.
You have to add some Code for the admin to respect your new model:
See: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
To Override the model you need to inherit from AbstractBaseUser:
from django.contrib.auth.models import AbstractBaseUser
class MyUser(AbstractBaseUser):
...
date_of_birth = models.DateField()
height = models.FloatField()
...
REQUIRED_FIELDS = ['date_of_birth', 'height']
AbstractBaseUser provides you all attributes of the default user model. So you don't have to take care of email, username, first_name, last_name, password etc.
More info about overriding the user model: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.models.CustomUser
In your settings link your new model:
AUTH_USER_MODEL = 'customauth.MyUser'
Please read the whole documentation of customizing the user model, there are some interesting hints for overriding the default manager, admin forms etc. Just remember that bigger changes in an existing project can be a big pain.
A short overview:
- Extend models.AbstractUser
- Set AUTH_USER_MODEL in settings.py
All details can be found here: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model
I inherited form the django user model like so:
from django.db import models
from django.contrib.auth.models import User, UserManager
from django.utils.translation import ugettext_lazy as _
class NewUserModel(User):
custom_field_1 = models.CharField(_('custom field 1'), max_length=250, null=True, blank=True)
custom_field_2 = models.CharField(_('custom field 2'), max_length=250, null=True, blank=True)
objects = UserManager()
When i go to the admin and add an entry into this model, it saves fine, but below the "Password" field where it has this text "Use '[algo]$[salt]$[hexdigest]' or use the change password form.", if i click on the "change password form' link, it produces this error
Truncated incorrect DOUBLE value: '7/password'
What can i do to fix this?
The best way to extend Django's User model is to create a new Profile model and identify it through the AUTH_PROFILE_MODULE setting. See http://www.b-list.org/weblog/2006/jun/06/django-tips-extending-user-model/, and http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users
This adds a get_profile() method to User instances which retrieves your associated model for a given User.
While doable (I did it once and regret it) using inheritance to extend the User model is not the best idea. I'd suggest you take Chris' advice and extend the User model with 1-1 relationship as it is the "standard" and "supported" way of doing it, and the way reusable apps deal with user profiles. Otherwise you need to implement an authentication backend if you want to do it by inheritance. So if you MUST do it see this. But be warned, you'll stumble across other problems later.