halilpazarlama halilpazarlama - 1 month ago 12
Python Question

Django 1.8+ extending the User model

I know this question has been asked hundreds of times, but most of them contain -accepted- answers that are not valid anymore. Some of them are for Django 1.5, some of them are even older.

So I'm looking for an up-to-date answer. The question that most resembles my problem is this one.

I'm using the

django-registration
module and I want users to have additional fields (like integer
user.points
). I'm OK with implementing my own
MyUser
model and changing the rest of my program accordingly. However I doubt this will work in compliance with the registration module. So I guess the ideal way would be keep using the
User
model, and somehow tie them so that whenever a
User
object is created, a corresponding
MyUser
object is created with the default values for additional fields.

-How- can I do this with Django 1.8+?

Thanks for any help,

Answer

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

class AccountManager(UserManager):
    def create_user(self, email, password=None, **kwargs):
        if not email:
            raise ValueError('Users must have a valid email address.')
        if not 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

    def create_superuser(self, email, password, **kwargs):
        account = self.create_user(email, password, **kwargs)
        account.is_staff = True
        account.is_superuser = True
        account.save()

        return account

class Account(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.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .models import Account

@admin.register(Account)
class UserAdmin(UserAdmin):
    pass
Comments