Django - 在Bootstrap表单中注册用户,并对确认密码进行校验及错误提示

前端开发 2026-07-09

我正在尝试使用Django 6和 Bootstrap 5创建一个注册用户表单。该表单会显示字段级别的验证/错误信息。然而,我不确定如何包含确认密码字段(及其错误/验证信息),因为该字段并非模型的一部分,但在保存表单之前需要确保密码正确。下面是源代码。是否有更好、更高效的方法以实现相同的输出(即在HTML表单上显示字段级别的错误/验证信息)?感谢 Francisco Alejandro Rojas 的代码贡献。

models.py

class UserMaster(models.Model):
    username = models.CharField(max_length=50, unique=True)
    password = models.CharField(max_length=15)

    def __str__(self):
        return self.username

forms.py

class UserMasterForm(forms.ModelForm):
    class Meta:
       model = UserMaster
       fields = ['username', 'password']
       widgets = {
            'username': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter User Name'}),
            'password': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Enter Password'}),
            'password2': forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Confirm Password'}),
          }
       error_messages = {
            'username': {
                'required': ('Username cannot be empty'),
                'unique': ('Username already taken')},
            'password': {
                'required': ('Password cannot be empty')},
          'password2': {
             'required': ('Confirmation password cannot be empty')},
        }

    def __init__(self, *args, **kwargs):
       super(UserMasterForm, self).__init__(*args, **kwargs)
       for field in iter(self.fields):
          self.fields[field].widget.attrs.update({'class': 'form-control', })

views.py

def register_view(request):
    if request.method == 'POST':
        form = UserMasterForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('login')
        else:
            change_class_for_error(form)
            return render(request, 'mainapp/register.html', {'form': form})
    else:
        form = UserMasterForm()
        return render(request, 'mainapp/register.html', {'form': form})

def change_class_for_error(myform):
    for field in myform:
        if field.errors:
            myform.fields[field.name].widget.attrs['class'] = 'form-control is-invalid'

signup.html

<form action="" class="g-3 mx-2" method="POST" novalidate>
{% csrf_token %}
<div class="row">
    <div class="col-md-5">
        <label class="form-label">Username</label>
        {{ form.username }}
        {% for error in form.username.errors  %}
            <div class="invalid-feedback">{{ error }}
        {% endfor %}
    </div>
</div>
<div class="row">
    <div class="col-md-6">
        <label class="form-label">Password</label>
        {{ form.password }}
        {% for error in form.password.errors  %}
            <div class="invalid-feedback">{{ error }}
        {% endfor %}
    </div>
    <div class="col-md-6">
        <label class="form-label">Confirm Password</label>
        <input class="form-control {% if form.errors %} is-invalid {% endif %}"
               name="password2" type="text" >
        {% for error in form.password2.errors  %}
            <div class="invalid-feedback">{{ error }}
        {% endfor %}
    </div>
    <div class="flex gap-3 mt-3 mb-2">
        <button class="btn btn-primary button-label rounded-0 w-25" type="submit">
            <a class="text-decoration-none" href="">Save</a>
        </button>
        <button class="btn btn-warning button-label rounded-0 w-25" type="button">
            <a class="text-decoration-none" href="#">Cancel</a>
        </button>
    </div>
</div>
</form>

解决方案

替代自行处理认证,您可以通过子类化 AbstractUser,创建一个在行为上与默认用户模型完全相同的自定义用户模型:

from django.contrib.auth.models import AbstractUser


class UserMaster(AbstractUser):
    pass

然后在你的settings.py中:

AUTH_USER_MODEL = 'users.UserMaster'

其中,'users 是拥有你的用户模型的应用的名称。

另外,在应用的admin.py中注册该模型:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import UserMaster

admin.site.register(UserMaster, UserAdmin)

你在表单中不需要添加密码或确认密码字段:

from django import forms
from django.contrib.auth.forms import (UserCreationForm) 

class UserMasterForm(forms.UserCreationForm):
    class Meta:
       model = UserMaster
       fields = ['username', 'email']

在你的模板中,即signup.html:

{% extends 'base.html' %}

{% load django_bootstrap5 %}

{% block title %}Sign Up{% endblock title %}
{% block content %}

<div class="signup-card">
<h2 class="text-primary">Sign Up</h2>
<form method="post">
  {% csrf_token %}
{% for field in form %}
  <div class="mb-3">
    <label class="form-label" style="width: 100%;">{{ field.label }}</label>
    {{ field }}
    {% if field.errors %}
      <div class="text-danger small">{{ field.errors }}</div>
    {% endif %}
  </div>
{% endfor %}
<button type="submit" class="btn btn-sm btn-primary">Sign Up</button>
</form>
</div>

{% endblock content %}

注: 这个解决方案在开始一个新项目时非常理想,因为在创建数据库表之后更改 AUTH_USER_MODEL 是可能的,但可能很复杂,因为它会影响外键和多对多关系等,例如。

此更改不能自动完成,需要手动修复你的模式,将数据从旧的用户表迁移,并且可能需要手动重新应用某些迁移。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章