user7627828
user7627828

Reputation:

How to add extra fields in User model and display them in Django admin?

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?

Upvotes: 9

Views: 32285

Answers (5)

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

Upvotes: 2

Raj Kushwaha R
Raj Kushwaha R

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

Ahtisham
Ahtisham

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

Zaheer Jan
Zaheer Jan

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

mxle
mxle

Reputation: 481

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.

Upvotes: 4

Related Questions