Django have many built-in features. One of them is an authentication system which allow us to create user, handle their permissions and allow them to create a login sessions. Django authentication system have its User model. This User model store information of user like username, password, email, name etc. Django authentication system also allow to create an anonymous sessions.
As User model is base model which have only important functionality, sometimes we need to extends its functionality to store some extra information like profile pic, phone etc.
Here's some steps to extend the default user model in Django, you can create a new model that has a one-to-one relationship with the Django User model. This allows you to add additional fields to store additional information about the user. Here's a high-level overview of the steps involved in extending the user model:
Quick Setup
If you haven't install python and django you can start from here Installing python and django
Create a virtual environment
python -m venv env
Activate virtual environment
source env/bin/activate
Installing Django
pip install django
Creating your first Project
django-admin startproject projectname
Creating your first App
Change to project directory: "cd projectname"
django-admin startapp appname
you see app have its own file structure, hence it is independent of the project. To work with app we need to include it in project
projectname/projectname/settings.py
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"whitenoise.runserver_nostatic",
"django.contrib.sitemaps",
"appname", # <-- add this
]
Create Profile Model
Here we create a Profile model which extends User model with one-to-one field
projectname/appname/models.py
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.Charfield(max_length=10)
profile_pic = models.ImageField(
upload_to='profile/')
def __str__(self):
return self.user.username
After Creating Profile model we need run some command to make changes into our database.
python manage.py makemigrations
This command is responsible for creating new migrations based on the changes you have made to your models.
python manage.py migrate
Above command is responsible for applying and unapplying migrations. This command actually change the database schema.
Signals for automate Profile instance
This is good as we can store some extra information about the user we created with User model, But all this work is manual, means we need to manually attach a User instance to Profile instance, which is sometimes not practical. But Django provide a solution to this issue.
We can signals which is also a built-in feature in django, allow to decoupled applications get notified when actions occur elsewhere in the framework. In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place.
projectname/appname/models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.exceptions import ObjectDoesNotExist
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.Charfield(max_length=10)
profile_pic = models.ImageField(
upload_to='profile/')
def __str__(self):
return self.user.username
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
This automate the process of creating Profile instance when a User instance is created.
Access Profile model data
This is pretty simple how you can access data the of Profile model from User model instance
user.profile.phone
Inside Template
<h2>{{ user.get_full_name }}</h2>
<p>Username: {{ user.username }}</p>
<p>phone: {{ user.profile.phone }}</p>
<img src="{{ user.profile.profile_pic.url }}" alt="profile pic" width="200" height="200">
Update Profile instance
def update_profile(request, user_id):
user = User.objects.get(pk=user_id)
user.profile.phone = "9898989898"
user.save()