【Django】教程-15-注册页面

发布于:2025-04-13 ⋅ 阅读:(39) ⋅ 点赞:(0)

【Django】教程-1-安装+创建项目+目录结构介绍
【Django】教程-2-前端-目录结构介绍
【Django】教程-3-数据库相关介绍
【Django】教程-4-一个增删改查的Demo
【Django】教程-5-ModelForm增删改查+规则校验【正则+钩子函数】
【Django】教程-6-搜索框-条件查询前后端
【Django】教程-7-分页,默认使用django的
【Django】教程-8-页面时间组件
【Django】教程-9-登录+退出
【Django】教程-10-ajax请求Demo,结合使用
【Django】教程-11-ajax弹窗实现增删改查
【Django】教程-12-柱状图
【Django】教程-13-饼图,折线图
【Django】教程-14-验证码+登录页

20. 注册页

重新写一个注册的ModelForm就可快速实现

forms.py

from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator, EmailValidator

from . import models
from .models import Department, UserInfo, Admin, Order
from .util.md5 import md5


class BootstrapModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 循环Modelform中所有字段,给每个字段插件设置
        for name, field in self.fields.items():
            if field.widget.attrs:
                field.widget.attrs["class"] = "form-control"
                field.widget.attrs["placeholder"] = field.label
            else:
                field.widget.attrs = {"class": "form-control", "placeholder": field.label}

    def as_div(self):
        """
        自定义表单渲染方法,将错误信息显示在字段下方并设置为红色
        """
        output = []
        for bound_field in self:
            label_html = f'<label for="{bound_field.id_for_label}">{bound_field.label}</label>'
            field_html = f'<div class="form-group">{label_html}{bound_field}</div>'
            if bound_field.errors:
                error_html = ''.join([f'<span class="text-danger">{error}</span>' for error in bound_field.errors])
                field_html += f'<div class="error-message">{error_html}</div>'
            output.append(field_html)
        return '\n'.join(output)


class PEPModelForm(forms.ModelForm):
    """ 手机号-P ,email-E, password-P, 用于需要手机号,邮箱,密码的form的父类,可以多继承"""
    email = forms.CharField(label="邮箱",
                            validators=[EmailValidator(message='请输入有效的电子邮件地址')],
                            widget=forms.TextInput(attrs={'class': 'form-control'})
                            )
    # 为 phone 字段添加自定义的正则表达式验证器,这里假设手机号是 11 位数字
    phone = forms.CharField(label="手机号",
                            validators=[
                                RegexValidator(
                                    regex=r'^1[3-9]\d{9}$',
                                    message='请输入有效的 11 位手机号码'
                                )
                            ],
                            widget=forms.TextInput
                            )
    password_regex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$'
    password_validator = RegexValidator(
        regex=password_regex,
        message="密码必须包含至少一个小写字母、一个大写字母、一个数字和一个特殊字符。"
    )
    password = forms.CharField(label="密码",
                               validators=[password_validator],
                               widget=forms.PasswordInput)

    def clean_password(self):
        password = self.cleaned_data.get("password")
        return md5(password)

# 注册Form
class RegisterForm(BootstrapModelForm, PEPModelForm):
    captcha = forms.CharField(label="验证码", widget=forms.TextInput())

    confirm_password = forms.CharField(label="确认密码", widget=forms.PasswordInput(render_value=True))

    class Meta:
        model = Admin
        # 字段按照顺序加载
        fields = ['username', 'password', 'confirm_password', 'captcha', 'phone', 'email']
        widgets = {
            "password": forms.PasswordInput(render_value=True)
        }

    def clean_confirm_password(self):
        password = self.cleaned_data.get("password")
        confirm_password = self.cleaned_data.get("confirm_password")
        if md5(confirm_password) != password:
            raise ValidationError("密码不一致")
        return confirm_password

我放到了login_view.py 里面了

import io

from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.views.decorators.csrf import csrf_exempt

from appTang.forms import LoginForm, RegisterForm
from appTang.models import Admin
from appTang.util.captcha_utils import generate_captcha

def register(request):
    """ 注册页面 """
    if request.method == 'GET':
        user = RegisterForm()
        return render(request, 'login/register.html', {"user": user})

    user = RegisterForm(data=request.POST)
    # print(user)
    if user.is_valid():
        # 校验验证码
        captcha = request.POST.get("captcha")
        image_code = request.session.get('captcha', '')  # 超时时,没有,给他个''
        # 不区分大小写比较
        if image_code.upper() == captcha.upper():
            user.save()
            return redirect("/login/")
        else:
            RegisterForm(data=request.POST)
            user.add_error('captcha', '验证码输入错误')
    return render(request, 'login/register.html', {"user": user})

register.html

{% load static %}
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户注册</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.css' %}"/>
    <style>
        body {
            background-color: #f8f9fa;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
        }

        .register-card {
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            padding: 2rem;
            width: 350px;
        }

        .form-group {
            margin-bottom: 1.5rem;
        }

        .form-control {
            height: calc(2.25rem + 2px);
        }

        .btn-register {
            width: 100%;
            padding: 0.75rem;
            background-color: #28a745;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        .btn-register:hover {
            background-color: #218838;
        }

        .login-link {
            text-align: center;
            margin-top: 1rem;
        }

        .login-link a {
            color: #007bff;
            text-decoration: none;
        }

        .login-link a:hover {
            text-decoration: underline;
        }

        /* 验证码相关样式 */
        .captcha-group {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 1.5rem;
        }

        .captcha-group img {
            cursor: pointer;
            margin-left: 10px;
        }
    </style>
</head>

<body>
<div class="container register-card">
    <h2 class="text-center mb-4">用户注册</h2>
    <form method="post" novalidate>
        {% csrf_token %}
        <div class="form-group">
            <label>用户名:</label>
            {{ user.username }}
            <span style="color: red">{{ user.username.errors.0 }}</span>
        </div>
        <div class="form-group">
            <label>密码:</label>
            {{ user.password }}
            <span style="color: red">{{ user.password.errors.0 }}</span>
        </div>
        <div class="form-group">
            <label>确认密码:</label>
            {{ user.confirm_password }}
            <span style="color: red">{{ user.confirm_password.errors.0 }}</span>
        </div>
         <div class="form-group">
            <label>邮箱:</label>
            {{ user.email }}
            <span style="color: red">{{ user.email.errors.0 }}</span>
        </div>
         <div class="form-group">
            <label>手机号:</label>
            {{ user.phone }}
            <span style="color: red">{{ user.phone.errors.0 }}</span>
        </div>
        <div class="form-group captcha-group">
            <label for="captcha">验证码:</label>
            <div class="captcha-input-img">
                <img id="captcha-image" class="img-fluid" src="/captcha/get">
                {{ user.captcha }}
                <span style="color: red">{{ user.captcha.errors.0 }}</span>

            </div>

        </div>
        <button type="submit" class="btn-register">注册</button>
    </form>
    <div class="login-link">
        已有账号?<a href="/login/">立即登录</a>
    </div>
</div>
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.js' %}"></script>
<script>
    $(document).ready(function () {
        $('#captcha-image').click(function () {
            $.ajax({
                url: '/captcha/get',
                type: 'GET',
                success: function (response) {
                    $('#captcha-image').attr('src', '/captcha/get');
                    $('input[name="captcha"]').val('');
                },
                error: function () {
                    alert('刷新验证码失败');
                }
            });
        });
    });
</script>
</body>

</html>

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到