👤 Creating User Profiles in Django (Extending the Auth System)
🔐 Mini-Series Reference
This is Part 3 of our Django Authentication Mini-Series:
👤 Create User Profiles (You are here)
Introduction
Often, the default user model isn’t enough to store all the data your app needs — things like profile pictures, bios, or social media links.
This post shows how to extend the user model with a separate profile model, keeping authentication clean while adding flexibility.
Step 1: Create a Profile Model
In your accounts/models.py
, add:
from django.conf import settings
from django.db import models
from django.dispatch import receiver
from django.db.models.signals import post_save
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
bio = models.TextField(blank=True)
avatar = models.ImageField(upload_to='avatars/', blank=True, null=True)
website = models.URLField(blank=True)
def __str__(self):
return f"{self.user.email}'s Profile"
# Signal to create or update profile automatically
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_or_update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
else:
instance.profile.save()
Step 2: Register Profile Model in Admin
In accounts/admin.py
:
from django.contrib import admin
from .models import Profile
admin.site.register(Profile)
Step 3: Update Forms to Include Profile Data
Create a ProfileForm
:
from django import forms
from .models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['bio', 'avatar', 'website']
Step 4: Create Profile Update View
In accounts/views.py
:
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from .forms import ProfileForm
@login_required
def profile_update(request):
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES, instance=request.user.profile)
if form.is_valid():
form.save()
return redirect('profile_update')
else:
form = ProfileForm(instance=request.user.profile)
return render(request, 'accounts/profile_update.html', {'form': form})
Step 5: Create Template for Profile Update
Create templates/accounts/profile_update.html
:
<h2>Update Profile</h2>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>
Step 6: Add URL for Profile Update
In accounts/urls.py
:
from django.urls import path
from . import views
urlpatterns = [
path('profile/', views.profile_update, name='profile_update'),
]
Conclusion
You’ve extended Django’s auth system with a powerful user profile feature that’s clean, flexible, and easy to maintain.
What’s Next?
🔄 In Part 4, we’ll implement Password Reset via Email, a critical feature for user-friendly apps.