Lesson 6: User Profiles – Because Everyone Deserves a Little Spotlight


Lesson 6

Lesson 6: User Profiles – Because Everyone Deserves a Little Spotlight

Congratulations, blog maestro! 🎉 You’ve mastered user registration, login, and comment restrictions. But let’s be real – without user profiles, your blog feels a bit like a party where everyone’s in costume but has no name tag. Time to give your users a profile they can show off!

In this lesson, we’ll add user profiles so each of your readers can have a unique identity. Think of it as giving each user a badge that says, “Yes, I belong here, and I’ve got opinions!”


Step 1: Activate the Virtual Environment (Your Coding Zen Mode)

Before we start, make sure you’re in your virtual environment, where all the magic happens.

source venv/bin/activate

If you see (venv) in your terminal, you’re officially in coding zen mode. 🧘‍♂️


Step 2: Install Pillow (For Image Handling Magic)

Since we’re adding profile pictures, Django needs the Pillow library to handle images. Let’s install it so Django can use ImageField for user profile pictures.

python3 -m pip install Pillow

Now that Pillow is installed, Django is ready to handle image fields!


Step 3: Extend the User Model (Adding a Little Spice to Your Users)

Django’s built-in user model is functional, but it lacks pizzazz. Let’s add some sparkle by creating a profile for each user, adding fields for a bio, profile picture, and anything else they might want.

File path: myblog/blog/models.py

Add this code below your Comment model:

from django.contrib.auth.models import User
from django.db import models

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
    bio = models.TextField(blank=True, null=True)
    profile_picture = models.ImageField(upload_to='profile_pics/', blank=True, null=True)

    def __str__(self):
        return f"{self.user.username}'s Profile"
  • user: Connects this profile to a Django user.
  • bio: A little space for users to write about themselves.
  • profile_picture: Because who doesn’t like a nice profile pic?

Step 4: Create and Apply Migrations (Making It Official)

Let’s tell Django we have a shiny new model. Run these commands to create and apply migrations:

python3 manage.py makemigrations
python3 manage.py migrate

Now, Django’s database officially recognizes your user profiles. The crowd goes wild! 🎉


Step 5: Handle Missing Profiles (Without Extra Coding)

If you have existing users, they might not have profiles yet. To make sure everyone has a profile, let’s use a one-time script in the Django shell to create profiles for any users who are missing one.

  1. Open the Django shell by running:

    python3 manage.py shell
    
  2. Run this code in the Django shell:

    from django.contrib.auth.models import User
    from blog.models import UserProfile
    
    for user in User.objects.all():
        if not hasattr(user, 'profile'):
            UserProfile.objects.create(user=user)
            print(f'Profile created for {user.username}')
    
  3. Exit the shell by typing:

    exit()
    

Now, every user should have a profile, even if they were created before this lesson!


Step 6: Add Signals to Automatically Create User Profiles for New Users

We don’t want users to go hunting for the “create profile” button. Let’s make it automatic using Django signals so that every new user automatically gets a profile.

File path: myblog/blog/signals.py

Create this file and add the following code:

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from .models import UserProfile

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

This way, every time a new user registers, Django will automatically create a profile for them.


Step 7: Register UserProfile in Admin (For Quick Peek at the Users)

We need to add UserProfile to the admin site so you can check out all the user profiles in one place.

File path: myblog/blog/admin.py

Add this code:

from django.contrib import admin
from .models import UserProfile

admin.site.register(UserProfile)

Now, head to your admin panel to see all user profiles lined up like a gallery of fame.


Step 8: Create a Profile Form (Because We Need a Fancy Form for Fancy People)

To let users edit their profile details, let’s create a profile form.

File path: myblog/blog/forms.py

Add this code below CustomUserCreationForm:

from .models import UserProfile

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ['bio', 'profile_picture']

Step 9: Add a Profile Update View (Let Users Show Off)

Let’s create a view that allows users to edit their profile information.

File path: myblog/blog/views.py

Add this code:

from django.contrib.auth.decorators import login_required
from .forms import UserProfileForm
from django.shortcuts import render, redirect

@login_required
def update_profile(request):
    profile = request.user.profile
    if request.method == 'POST':
        form = UserProfileForm(request.POST, request.FILES, instance=profile)
        if form.is_valid():
            form.save()
            return redirect('profile')
    else:
        form = UserProfileForm(instance=profile)
    return render(request, 'profile/update_profile.html', {'form': form})

This view lets users update their profile details – perfect for adding that “I’m a cat person” bio.


Step 10: Create Profile Templates (A Place for Your Shiny Profile)

Now, let’s create templates for updating the profile.

File path:

myblog/
    blog/
        templates/
            profile/
                update_profile.html

Here’s what the template could look like:

{% extends "base.html" %}

{% block title %}Update Profile{% endblock %}

{% block content %}
<h2>Update Your Profile</h2>
<form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Save Changes</button>
</form>
{% endblock %}

This template provides a form to upload a profile picture and add a bio. Very fancy, indeed.


Step 11: Add a URL for Profile Update View

Add a URL pattern to allow users to access the profile update page.

File path: myblog/blog/urls.py

Add this code:

from . import views

urlpatterns = [
    path('', views.blog_index, name='blog_index'),
    path('post/<int:pk>/', views.blog_post_detail, name='blog_post_detail'),
    path('register/', views.register, name='register'),
    path('profile/', views.update_profile, name='profile'),
]

Now users can access their profile update page at /profile/.


Step 12: Test It Out! (Profile Glam-Up Time)

Fire up the server and take your new profile feature for a spin:

python3 manage.py runserver

Head over to /profile/ and try updating your user profile. Add a bio, upload a profile picture, and let your personality shine.


Step 13: Deactivate the Virtual Environment (Farewell, Coding Zen)

When you’re done, remember to exit your virtual environment:

deactivate

Back to reality, with a working profile feature and a community full of vibrant user profiles.


Lesson 6 Recap

Ta-da! 🎉 You’ve added user profiles to your Django blog. Now each user has a place to showcase their bio and a profile picture, adding a touch of personality to your blog.

In the next lesson, we’ll dive into even more ways to customize the user experience. But for now, enjoy watching your users’ profiles bring your blog to life. Cheers to making your blog a little more like Hogwarts – everyone with their own unique identity! 🧙‍♂️✨


See also