Add Custom User Model (with custom fields like phone no, profile picture) to django or wagtail sites

Altaf
4 min readAug 15, 2021

--

According to django documentation, you should create a custom user model whenver you start a django project. Because then you will have full control over the fields of the user objects in django, and you can add as many custom fields to the user model as you need and whenever you need. If you do not create a custom user model at the beginning of a project and later you need some custom fields added to your user model (like phone no , profile picture etc.) , you will face some complexities doing so.

So, in this article I will explain how to create a custom user model for a django and wagtail site. I will explain the things from creating a new django project.

Please do not run migrate command until we create custom user model, otherwise django built-in user model related tables, fields, foreign key references etc. will be added to the database instead of using custom user model

Go inside the folder where you want to create the django project and then run following command:

django-admin startproject custom_user_model

Now if you want to use wagtail (which is a open source cms and has been built on the django framework) then install wagtail in your development environment and make necessary configuration changes to your project. I am not explaining the details about wagtail installation and configuration changes here. You will find lots of tutorials and suggestions online for this.

Go inside your project root folder “custom_user_model” and create an app for your website:

python manage.py startapp website

Here website application is your main app where all your project codes / models / views etc. will exist. I will suggest to create a separate app for the Cusom User Model. This way custom user model will be independent of your website project and you can easily use this custom user model app to any other django projects you want. So, run following command to create custom user model app:

python manage.py startapp users

You will see a “users” folder will be created for this app.

Open models.py from users app and create the cusom user model class extending AbstractUser base class from django auth models:

from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
phone = models.CharField(verbose_name='phone', max_length=30)
profile_pic = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
)

Here I used a foreign key reference for profile_pic field for wagtail project. Wagtail has a custom Image model of its own, I used it for my wagtail project so that I can easily add these custom fields to wagtail admin panel to add / edit new users. For django project you can ignore using foreign key and add a profile_pic field to the custom model as below:

profile_pic = models.ImageField(upload_to='upload_folder_path')

Extend wagtail.users.forms.UserEditForm and wagtail.users.forms.UserCreationForm . Add following codes in admin.py file of the users app. These codes are used to integrate custom user model and custom fields to wagtail admin panel so that you can manage (add / edit) users from wagtail admin panel. please ignore this step if you are not using wagtail in your project.

from wagtail.users.forms import UserEditForm, UserCreationForm
from wagtail.images.widgets import AdminImageChooser
from wagtail.images import get_image_model
class CustomUserEditForm(UserEditForm):
phone = forms.CharField(max_length=30, required=True, label=_("Phone"))
profile_pic = forms.ModelChoiceField(
queryset=get_image_model().objects.all(), widget=AdminImageChooser(), label=_('Profile Picture'),
)
class CustomUserCreationForm(UserCreationForm):
phone = forms.CharField(max_length=30, required=True, label=_("Phone"))
profile_pic = forms.ModelChoiceField(
queryset=get_image_model().objects.all(), widget=AdminImageChooser(), label=_('Profile Picture'),
)

Extend wagtail user create and edit template file to add and edit users from wagtail admin panel. Ignore this step too if you are not using wagtail in your project.

Please create following file in your application templates folder: wagtailusers/users/create.html and add following codes:

{% extends "wagtailusers/users/create.html" %}{% block extra_fields %}
{% include "wagtailadmin/shared/field_as_li.html" with field=form.phone %}
{% include "wagtailadmin/shared/field_as_li.html" with field=form.profile_pic %}
{% endblock extra_fields %}

Please create following file in your application templates folder: wagtailusers/users/edit.html and add following codes:

{% extends "wagtailusers/users/edit.html" %}{% block extra_fields %}
{% include "wagtailadmin/shared/field_as_li.html" with field=form.phone %}
{% include "wagtailadmin/shared/field_as_li.html" with field=form.profile_pic %}
{% endblock extra_fields %}

Add following configurations in your settings.py file:

AUTH_USER_MODEL = 'users.User'WAGTAIL_USER_EDIT_FORM = 'users.admin.CustomUserEditForm'
WAGTAIL_USER_CREATION_FORM = 'users.admin.CustomUserCreationForm'
WAGTAIL_USER_CUSTOM_FIELDS = ['phone','profile_pic']

Please note that in above configuration the prefix “users” because it is the name of the django application where I added the custom user model and the extended CustomUserEditForm and CustomUserCreationForm forms (under admin.py) as explained above.

Here AUTH_USER_MODEL refers to the custom user model class. By this settings, django will know that it needs to consider this custom user model instead of the built-in django auth user model for authentication and other purposes. Other settings are for wagtail , from those settings wagtail will know which form class to use for add / edit users from admin panel and what are the new fields of custom user model.

Add both website and users app to the Installed Apps settings of settings.py in your project:

INSTALLED_APPS = [
# This project
'website',
'users',#This app MUST be above 'wagtail.users' and 'django.contrib.auth' BECAUSE this app contains CUSTOM user model.
'wagtailfontawesome',
'wagtailcache',
'wagtailimportexport',
# Wagtail
'wagtail.contrib.forms',
'wagtail.contrib.redirects',
'wagtail.embeds',
'wagtail.sites',
'wagtail.users',
'wagtail.snippets',
'wagtail.documents',
'wagtail.images',
'wagtail.search',
'wagtail.core',
'wagtail.contrib.settings',
'wagtail.contrib.modeladmin',
'wagtail.contrib.table_block',
'wagtail.admin',
'wagtail.api.v2',
# Django
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sitemaps',
]

Please note that ‘users’ app must need to be placed above ‘wagtail.users’ and ‘django.contrib.auth’ apps. This way, django will find the custom user model first and consider it as the user model of the project instead of other user models exists in some other apps. Please ignore all other apps mentioned above, those are just some sample wagtail / django apps which you may or may not need in your project.

Thanks for reading this article.

--

--

Altaf

I am a software engineer , specialized in microsoft platform and python development, always enthusiastic in learning new things