Reputation:
I'm learning Django and need some help.
I need to include an extra boolean field in my User Model (auth_user table in the db I believe) and have it be displayed in the admin interface when managing users, like the staff status field in this image...
127:0.0.1:8000/admin/user :
and...
127.0.0.1:8000/admin/auth/user/2/change/ :
I'm unsure on how to approach this. I understand I'll have to extend the AbstractUser model and then perhaps manually add the field into the db, but then how do I update the new field for the view, form and templates for the admin interface? Will I have to rewrite the django admin source code for all of these or is there an simpler way?
Upvotes: 9
Views: 32285
Reputation: 1
You can extend User model with OneToOneField() to add extra fields. *You can also see my answer explaining how to set up email
and password
authentication with AbstractUser or AbstractBaseUser and PermissionsMixin.
First, run the command below to create account
app:
python manage.py startapp account
Then, set account
app to INSTALLED_APPS in settings.py
as shown below:
# "settings.py"
INSTALLED_APPS = [
...
"account", # Here
]
Then, create UserProfile
model in account/models.py
as shown below. *user
field extends User
model with OneToOneField()
:
# "account/models.py"
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(
User,
verbose_name=_("user"),
on_delete=models.CASCADE
)
age = models.PositiveSmallIntegerField(_("age"))
gender = models.CharField(_("gender"), max_length=20)
married = models.BooleanField(_("married"))
Then, create UserProfileInline
and UserAdmin
classes in account/admin.py
as shown below. *With admin.site.unregister(User)
, unregistering User
model registered by default is necessary otherwise there is error:
# "account/admin.py"
from django.contrib import admin
from .models import UserProfile
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
admin.site.unregister(User) # Necessary
class UserProfileInline(admin.TabularInline):
model = UserProfile
@admin.register(User)
class UserAdmin(BaseUserAdmin):
inlines = (UserProfileInline,)
Then, run the command below:
python manage.py makemigrations && python manage.py migrate
Then, run the command below:
python manage.py runserver 0.0.0.0:8000
Finally, you could extend User
model with extra fields as shown below:
Upvotes: 2
Reputation: 1
#managers.py Create new file.
from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _
class CustomUserManager(BaseUserManager):
def create_user(self, email, password, **extra_fields):
if not email:
raise ValueError(_('The Email must be set'))
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff=True.'))
if extra_fields.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))
return self.create_user(email, password, **extra_fields)
#models.py Create your models here.
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import gettext_lazy as _
from .managers import CustomUserManager
class User(AbstractBaseUser,PermissionsMixin):
first_name =models.CharField(max_length=250)
email = models.EmailField(_('email address'), unique=True)
mobile =models.CharField(max_length=10)
status = models.BooleanField(default=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
object =CustomUserManager()
# add more your fields
#admin.py
from django.contrib import admin
from .models import User
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
list_display = ('email','mobile','password')
#setting.py
AUTH_USER_MODEL = 'users.User'
# run command
python manage.py makemigrations
python manage.py migrate
Upvotes: 0
Reputation: 10136
This is how I did it:
Note: This should be done when you are creating a new project.
Adding field(s) to User model :-
models.py:
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
gender = models.BooleanField(default=True) # True for male and False for female
# you can add more fields here.
Overriding the default User model :-
settings.py:
# the example_app is an app in which models.py is defined
AUTH_USER_MODEL = 'example_app.User'
Displaying the model on admin page :-
admin.py:
from django.contrib import admin
from .models import User
admin.site.register(User)
Upvotes: 11
Reputation: 243
The best way is to create new Model with User OneToOneField. e.g
class UserProfile(models.Model):
user = models.OneToOneField(User)
phone = models.CharField(max_length=256, blank=True, null=True)
gender = models.CharField(
max_length=1, choices=(('m', _('Male')), ('f', _('Female'))),
blank=True, null=True)
You can play with django admin either in User Model or UserProfile Model and can display the fields in Admin accordingly
Upvotes: 10