ここではユーザが自身でユーザ登録できるような機能を実装します.
  まず,Django contrib の auth にある forms.py から class UserCreationForm(forms.ModelForm): をコピーし,僅かな編集を施します.
users/forms.py
class UserCreationForm(forms.ModelForm):
    """
    A form that creates a user, with no privileges, from the given username and
    password.
    """
    error_messages = {
        "password_mismatch": _("The two password fields didn’t match."),
    }
    password1 = forms.CharField(
        label=_("Password"),
        strip=False,
        widget=forms.PasswordInput(attrs={"autocomplete": "new-password", 'class': 'form-control'}),
        help_text=password_validation.password_validators_help_text_html(),
    )
    password2 = forms.CharField(
        label=_("Password confirmation"),
        widget=forms.PasswordInput(attrs={"autocomplete": "new-password", 'class': 'form-control'}),
        strip=False,
        help_text=_("Enter the same password as before, for verification."),
    )
    class Meta:
        model = UserModel
        fields = ("username",)
        field_classes = {"username": UsernameField}
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self._meta.model.USERNAME_FIELD in self.fields:
            self.fields[self._meta.model.USERNAME_FIELD].widget.attrs[
                "autofocus"
            ] = True
    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise ValidationError(
                self.error_messages["password_mismatch"],
                code="password_mismatch",
            )
        return password2
    def _post_clean(self):
        super()._post_clean()
        # Validate the password after self.instance is updated with form data
        # by super().
        password = self.cleaned_data.get("password2")
        if password:
            try:
                password_validation.validate_password(password, self.instance)
            except ValidationError as error:
                self.add_error("password2", error)
    def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user
ユーザ登録のための URL を定義します.
users\urls.py
from django.urls import path
from . import views
app_name = 'users'
urlpatterns = [
    path('', views.users_index, name='index'),
    path('<int:user_id>/', views.users_profile, name='profile'),
    path('<int:user_id>/update/', views.users_update, name='update'),
    path('login/', views.LoginView.as_view(), name='login'),
    path('logout/', views.LogoutView.as_view(), name='logout'),
    path('password/', views.PasswordChangeView.as_view(), name='password_change_form'),
    path('password_change_done/', views.PasswordChangeDoneView.as_view(), name='password_change_done'),
    # ユーザ登録
    path('create/', views.UserCreateView.as_view(), name='create'),
    # パスワードリセットのメール送信画面
    path('password_reset/', views.PasswordResetView.as_view(), name='password_reset'),
    # メール送信後の画面
    path('password_reset/done/', views.PasswordResetDoneView.as_view(), name='password_reset_done'),
    # メールリンクから呼び出される
    path('reset/<uidb64>/<token>/', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    path('reset/done/', views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]
続いて views.py を編集します.
users/views.py
from urllib.parse import urlparse, urlunparse
from django.conf import settings
# Avoid shadowing the login() and logout() views below.
from django.contrib.auth import REDIRECT_FIELD_NAME, get_user_model
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
# from django.contrib.auth.forms import (
#    AuthenticationForm,
#    PasswordChangeForm,
#    PasswordResetForm,
#    SetPasswordForm,
# )
from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.http import HttpResponseRedirect, QueryDict
from django.shortcuts import resolve_url
from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
from django.utils.http import url_has_allowed_host_and_scheme, urlsafe_base64_decode
from django.utils.translation import gettext_lazy as _
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.debug import sensitive_post_parameters
from django.views.generic.base import TemplateView
from django.views.generic.edit import FormView
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from django.shortcuts import redirect
from django.urls import reverse
from django.contrib import messages
from django.views.generic import CreateView
# from django.shortcuts import redirect
# from django.urls import reverse
from .forms import UserForm
from .forms import AuthenticationForm
from .forms import PasswordChangeForm
from .forms import SetPasswordForm
from .forms import PasswordResetForm
from .forms import UserCreationForm
UserModel = get_user_model()
...(中略)...
class UserCreateView(CreateView):
    template_name = 'users/create_form.html'
    form_class = UserCreationForm
    def form_valid(self, form):
        messages.success(self.request, 'ユーザ登録しました')
        user = form.save()
        return HttpResponseRedirect("/")
ユーザ登録ページの HTML を作成します.
users/templates/users/create_form.html
{% extends "base.html" %}
{% block title %}
ユーザ登録
{% endblock %}
{% block content %}
<h1 class="my-5">コメントアプリケーション</h1>
<div class="card">
  <div class="card-header">ユーザ登録</div>
  <div class="card-body">
      <form method="post">
          {% csrf_token %}
          {{ form.as_p }}
          <button type="submit" class="btn btn-primary btn-block">
            ユーザ登録
          </button>
      </form>
  </div>
  <div class="card-footer">
      <p>
      </p>
  </div>
</div>
{% endblock content %}
ログイン前の Navbar にユーザ登録のリンクを作成します.
comments/templates/base.html
{% if user.is_authenticated %}
    <ul class="navbar-nav ml-auto">
        <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
            {{ user.username }}
            </a>
            <ul class="dropdown-menu">
                <li><a class="dropdown-item" href="{% url 'users:profile' user.id %}">Profile</a></li>
                <li><a class="dropdown-item" href="{% url 'users:update' user.id %}">Edit Profile</a></li>
                <li><a class="dropdown-item" href="{% url 'users:password_change_form' %}">Change Password</a></li>
                <li><a class="dropdown-item" href="#">Action</a></li>
                <li><a class="dropdown-item" href="#">Another action</a></li>
                <li><hr class="dropdown-divider"></li>
                <li><a class="dropdown-item" href="{% url 'users:logout' %}">ログアウト</a></li>
            </ul>
        </li>
    </ul>
{% else %}
    <ul class="navbar-nav ml-auto">
        <li class="nav-item">
            <a class="nav-link" href="{% url 'users:create' %}">Register</a>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="{% url 'users:index' %}">Login</a>
        </li>
    </ul>
{% endif %}
ログイン前のトップページに Register リンクが表示されるようになりました.この Register をクリックします.
ユーザ名とパスワードを設定してユーザ登録します.
登録できれば次の画面に移動します.
いま作成したユーザ名でログインやログアウトができることを確認してください.