Django 1.8+ Extending The User Model
Solution 1:
An article about the topic: How to Extend Django User Model
What I use is the One-To-One
approach:
classUserProfile(models.Model):
user = models.OneToOneField(User, related_name="profile")
#more fields @staticmethod @receiver(post_save, sender=User, dispatch_uid="at_user_post_save")defuser_post_save(sender, instance, **kwargs):
#create new profile on user.save() (if necessary)
profile, new = UserProfile.objects.get_or_create(user=instance)
#in view
profile = request.user.profile
UPDATE:
Are there any other caveats? Like what happens when I remove a UserProfile?
UserProfile
is the one who holds the relation, so on delete no user
should be deleted. You can control what must be the behavior when a user
gets deleted via the on_delete
kwarg.
Also do they always have the same private keys?
No each class have its own PKs, just the UserProfile
holds the PK to its user
.
OneToOneField
is in conceptually a ForeignKey
with an unique=True
, the big difference is that the reverse side of the relation do not return a list with 0/1 elements, but the element itself or raise DoesNotExist
or None
if null=True
.
The only thing which I don't like in this approach is that you always have to do 1 more query to get user.profile
. I still can't find a good and clean approach to always .select_related('profile')
when a new user
is fetched from auth
, but this is more of a problem of the authentication system rather than the approach itself.
Solution 2:
django-registration
supports custom user models, so it won't be a problem to create your own user model and use it with django-registration
.
All you need to do is to create registration form based on registration.forms.RegistrationForm
and then use it in RegistrationView
. You also need to keep email
and is_active
fields from default django user model and provide email_user
method in user model. USERNAME_FIELD
also must be specified. Other requirements depends of your authentication method.
More on that you can find in django-registration
docs.
Solution 3:
First req for extending the user model: you have to start with a clean django project that you have not called the: "python manage.py migrate" command on.
This is because if you did migrated in the past, the un-extanded user model is already created an django doesn't know how to change it.
Now, to choose another user model the first thing you have to do is on your settings.py:
AUTH_USER_MODEL = 'APPNAME.Account'
It is recommended to create a new app to handle the user model. be aware not to call the app "account", as it collides with the already existing user model.
I created An app called accountb. on the models:
from django.db import models
from django.contrib.auth.models import UserManager
from django.contrib.auth.models import AbstractUser
classAccountManager(UserManager):
defcreate_user(self, email, password=None, **kwargs):
ifnot email:
raise ValueError('Users must have a valid email address.')
ifnot kwargs.get('username'):
raise ValueError('Users must have a valid username.')
account = self.model(
email=self.normalize_email(email),
username=kwargs.get('username'),
year_of_birth = kwargs.get('year_of_birth'),
#MODEL = kwargs.get('MODEL_NAME'),
)
account.set_password(password)
account.save()
return account
defcreate_superuser(self, email, password, **kwargs):
account = self.create_user(email, password, **kwargs)
account.is_staff = True
account.is_superuser = True
account.save()
return account
classAccount(AbstractUser):
email = models.EmailField(unique=True)
#ADD YOUR MODELS HERE
objects = AccountManager()
def__str__(self):
return self.email
Also, dont forget to register it on admin.py:
from django.contribimport admin
from .modelsimportAccount
admin.site.register(Account)
Post a Comment for "Django 1.8+ Extending The User Model"