-
Create a dedicated app
accounts
and define , and [[Define app URLs under their own path]]. -
URL: create a
signup
path inaccounts/urls.py
:
from django.urls import path
from . import views
urlpatterns = [
path('signup/', views.signup, name='signup')
]
- View: define
signup
view and pass theUserCreationForm
as the sign up form:
from django.shortcuts import render
from django.contrib.auth.forms import UserCreationForm
def signup(request):
return render(request, 'accounts/signup.html', { 'form': UserCreationForm })
- Template: create template
accounts/templates/accounts/signup.html
and simply render the form:
{{ form }}
- Improve template: make the template extend from base.html, render the fields of
form
as<p>
and wrap them in aform
tag and have asubmit
button:
{% extends 'base.html' %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign up</button>
</form>
{% endblock content %}
- Create user on submitting and handler errors:
# views.py
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.contrib.auth import login
from django.db import IntegrityError
def signup(request):
if request.method == 'GET':
return render(request, 'accounts/signup.html', { 'form': UserCreationForm })
else:
if request.POST['password1'] == request.POST['password2']:
try:
user = User.objects.create_user(
request.POST['username'],
password=request.POST['password1']
)
user.save()
login(request, user)
return redirect('/')
except IntegrityError:
return render(request, 'accounts/signup.html',
{ 'form': UserCreationForm, 'error': 'Username already taken. Choose new username.'})
else:
return render(request, 'accounts/signup.html',
{ 'form': UserCreationForm, 'error': 'Passwords do not match.'})
In template file, display the error if exists:
{% if error %}
<div class=""alert">{{ error }}</div>
{% endif %}