9

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 :

enter image description here

and...

127.0.0.1:8000/admin/auth/user/2/change/ :

enter image description here

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?

1

5 Answers 5

11

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) 
Sign up to request clarification or add additional context in comments.

1 Comment

I am getting error Manager is not available
10

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

1 Comment

How these fields can be displayed after migration?
4

You have two options, they are:

  1. Extend the existing User model by adding another model and linking it to the User model using one-to-one relation. See here.

  2. Write your own user model and use it, which would be difficult for a newbie. See here.

Comments

2

July, 2023 Update:

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:

enter image description here

Comments

0
#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 

Comments