Registration

Create accounts with Django forms, hashed passwords, and a matching Profile row.

Goal for this part

Let a new neighbor create an account. Django hashes the password. A signal (or form save) creates the matching Profile so you never have a User without a public page.

Why Django’s User, not a custom table

Django’s User already stores username, email, and a PBKDF2 (or Argon2) hash. Building your own users table is how tutorials store plaintext passwords. We keep the default user model and hang Westloop fields on Profile.

Walkthrough

# accounts/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Profile

class RegisterForm(UserCreationForm):
    email = forms.EmailField(required=True)
    display_name = forms.CharField(max_length=80)
    neighborhood = forms.CharField(max_length=80, required=False)

    class Meta:
        model = User
        fields = ("username", "email", "display_name", "neighborhood", "password1", "password2")

    def save(self, commit=True):
        user = super().save(commit=commit)
        Profile.objects.update_or_create(
            user=user,
            defaults={
                "display_name": self.cleaned_data["display_name"],
                "neighborhood": self.cleaned_data.get("neighborhood", ""),
            },
        )
        return user

After a valid POST, log the user in immediately so they land on the feed as themselves — social apps that force a second login feel broken.

from django.contrib.auth import login
from django.shortcuts import redirect, render
from .forms import RegisterForm

def register(request):
    form = RegisterForm(request.POST or None)
    if request.method == "POST" and form.is_valid():
        user = form.save()
        login(request, user)
        return redirect("posts:feed")
    return render(request, "accounts/register.html", {"form": form})

How to run it and what you should see

Open /accounts/register/, create mina with a real-looking email, and submit. You should return to the feed signed in (the nav will still say “Sign in” until the next part wires the session into the header). A second submit of the same username must show a form error, not a 500.

Common mistakes

Skipping UserCreationForm means you may store raw passwords. Creating a User without a Profile will crash profile pages later. Email is required here so password reset in part 11 has somewhere to send mail.

Try this

Register with two different passwords and confirm the form refuses. Then register cleanly and inspect the auth_user row — the password column must start with a hasher prefix such as pbkdf2_sha256$, never the plaintext.