首页 > 其他分享 >订单交易平台四:登录界面(使用Forms组件解决小bug)

订单交易平台四:登录界面(使用Forms组件解决小bug)

时间:2024-10-06 22:33:59浏览次数:1  
标签:forms form self 校验 class Forms 组件 data bug

总任务:

  • 使用Forms组件解决用户输入错误、空,并且展示错误信息在输入框的下面
  • 解决用户校验,以及用户提交之后还可以将第一次输入的东西继续展示到页面

1.示例

1.1 先导入forms第三方模块包,并且写入我们前端组要校验的字段

```
from django import forms

class LoginForm(forms.Form):
    role = forms.ChoiceField(
        required=True, # 校验输入是否为空
        label='角色',
        choices=(('2', '客户'), ('1', '管理员')),
        widget=forms.Select(attrs={"class": "form-control"})   # attr这里可以写前端的样式
    )
    # <input type = "text" class ="form-control" placeholder="用户名" name="username" >
    username = forms.CharField(
        required=True,
        label='用户名',
        widget=forms.TextInput(attrs={"class": "form-control", "placeholder": "用户名"})
    )
    password = forms.CharField(
        required=True,
        label='密码',
        widget=forms.PasswordInput(attrs={"class": "form-control", "placeholder": "密码"})
    )
```

1.2 在views.py函数里面实例化一下此类

```
def login(request):
    if request.method == "GET":
        form = LoginForm()
    return render(request, "login.html", {"form": form})
```
  • 在前端进行渲染,将username文本框进行替换
    img

1.3 is_valid()校验数据

![img](/i/l/?n=24&i=blog/3339660/202410/3339660-20241006165535136-587355920.png)

 ```
  # 如果校验不成功,则继续返回给页面原本的数据,如果校验成功,则返回一个校验成功之后数据的字典 
  ```

1.4使用到form组件总结

```
class LoginForm(forms.Form):
    role = forms.ChoiceField(
        required=True,
        choices=(("2", "客户"), ("1", "管理员")),
        widget=forms.Select(attrs={"class": "form-control"})
    )
    username = forms.CharField(
        initial="wupeiqi",
        required=True,
        正则表达式
        widget=forms.TextInput(attrs={"class": "form-control", "placeholder": "用户名"})
    )
    
    # 自定义方法(钩子)
    def clean_username(self):
        raise 异常
		return 123
    
form = LoginForm(initial={"username":"xxx","password":"xx"})


- 生成HTML标签 + 携带数据

  - 保留原来提交的数据,不再担心form表单提交时页面刷新。
  - 显示默认值,做编辑页面显示默认值。

- 数据校验,对用户提交的数据格式校验

  form = LoginForm(data=request.POST)
  if form.is_valid():
      print(form.cleaned_data)
  else:
      print(form.errors)

```

2.优化改进(及所需使用form组件功能)

2.1 前端加入for循环,解决字段过多导致代码冗余

img

# ==================================第一部分==================================

class LoginForm(forms.Form):
  role = forms.ChoiceField(
      required=True,
      label='角色',
      choices=(('2', '客户'), ('1', '管理员')),
      widget=forms.Select(attrs={"class": "form-control"})
  )
  # <input type = "text" class ="form-control" placeholder="用户名" name="username" >
  username = forms.CharField(
      required=True,
      label='用户名',
      widget=forms.TextInput(attrs={"class": "form-control", "placeholder": "用户名"})
  )
  password = forms.CharField(
      required=True,
      label='密码',
      widget=forms.PasswordInput(attrs={"class": "form-control", "placeholder": "密码"}),
      render_value=True
  )

==================================第二部分==================================
{% for field in form %}
          <div class="form-group">
              <label>{{ field.label }}</label>
              {{ field }}
          </div>
      {% endfor %}

2.2 forms组件类中加入限制字段的数量,以及加入错误提示

img

2.3 form校验的流程

  • 每个字段的内部:required + validators + min_length=6,max_length=10

  • 字段的钩子方法

    def clean_username(self):
        user = self.cleaned_data['username']
        # 校验规则
        # 校验失败
        if len(user) < 3:
            from django.core.exceptions import ValidationError
            raise ValidationError("用户名格式错误")
    	return user
    
    print(form.cleaned_data)
    
  • clean

    def clean(self):
        # 对所有值进行校验
        from django.core.exceptions import ValidationError
        # 1.不返回值,默认 self.cleaned_data
        # 2.返回值,self.cleaned_data=返回的值
        # 3.报错,ValidationError ->  self.add_error(None, e)
    
  • _post_clean

    def _post_clean(self):
        pass
    

2.4 form钩子的实际运用

```
class LoginForm(forms.Form):
  role = forms.ChoiceField(
      required=True,
      label='角色',
      choices=(('2', '客户'), ('1', '管理员')),
      widget=forms.Select(attrs={"class": "form-control"})
  )
  # <input type = "text" class ="form-control" placeholder="用户名" name="username" >
  username = forms.CharField(
      required=True,
      label='用户名',
      widget=forms.TextInput(attrs={"class": "form-control", "placeholder": "用户名"})
  )
  password = forms.CharField(
      required=True,
      label='密码',
      widget=forms.PasswordInput(attrs={"class": "form-control", "placeholder": "密码"}),
      render_value=True
  )

  def clean_username(self):
      user = self.cleaned_data['username']
      # 校验规则
      # 校验失败
      if len(user) < 3:
          from django.core.exceptions import ValidationError
          raise ValidationError("用户名格式错误")
      return user

  def clean_password(self):
      return md5(self.cleaned_data['password'])

  def clean(self):
      # 对所有值进行校验,无论前面的字段校验成功与否
      user = self.cleaned_data.get('username')
      pwd = self.cleaned_data.get('password')
      if user and pwd:
          pass
      from django.core.exceptions import ValidationError
      # 1.不返回值,默认 self.cleaned_data
      # 2.返回值,self.cleaned_data=返回的值
      # 3.报错,ValidationError ->  self.add_error(None, e)
      # print(self.cleaned_data)
      # raise ValidationError("整xxxxx体错误")

  def _post_clean(self):
      pass
```

2.5 如果想要让错误展示在某个字段的下面(form.add.error)

img

2.6 form校验源码解析

img
img
img
img

2.7 登录界面代码最终版

  • 总共分为3个文件

2.7.1 前端login.html文件

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.css' %}">
<style>
        .box {
            width: 450px;
            border: 1px solid #f0f0f0;
            margin-left: auto;
            margin-right: auto;
            margin-top: 100px;

            padding-left: 40px;
            padding-right: 40px;
            padding-bottom: 30px;

            box-shadow: 5px 10px 10px rgb(0 0 0 / 5%);
        }
    </style>
</head>
<body>

<div class="box">
    <h2 style="text-align: center;">用户登录</h2>
    <form method="post">
        {% csrf_token %}

        {% for field in form %}
            <div class="form-group" style="position: relative;margin-bottom: 25px">
                <label>{{ field.label }}</label>
                {{ field }}
                <span style="color: red;position: absolute;">{{ field.errors.0 }}</span>
            </div>
        {% endfor %}

        <button type="submit" class="btn btn-primary">登 录</button>

        <a href='{% url 'sms_login' %}' style="float: right;">短信登录</a>
    </form>
</div>

</body>
</html>

2.7.2 后端account.py文件

# -*- coding utf-8 -*-
import random

from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.http import JsonResponse
from django.shortcuts import render, redirect
from django_redis import get_redis_connection

from web import models
from utils.encrypt import md5
from utils import tencent
from django import forms

"""
@version : python 3.10
@author : T-mars
@file : xxx.py
@time : 2023-10-28 下午13:20
"""


class LoginForm(forms.Form):
    role = forms.ChoiceField(
        required=True,
        label='角色',
        choices=(('2', '客户'), ('1', '管理员')),
        widget=forms.Select(attrs={"class": "form-control"})
    )
    # <input type = "text" class ="form-control" placeholder="用户名" name="username" >
    username = forms.CharField(
        required=True,
        label='用户名',
        widget=forms.TextInput(attrs={"class": "form-control", "placeholder": "用户名"})
    )
    password = forms.CharField(
        required=True,
        label='密码',
        widget=forms.PasswordInput(attrs={"class": "form-control", "placeholder": "密码"}),
        # render_value=True
    )

    def clean_username(self):
        user = self.cleaned_data['username']
        # 校验规则
        # 校验失败
        if len(user) < 3:
            from django.core.exceptions import ValidationError
            raise ValidationError("用户名格式错误")
        return user

    def clean_password(self):
        return md5(self.cleaned_data['password'])

    def clean(self):
        # 对所有值进行校验,无论前面的字段校验成功与否
        user = self.cleaned_data.get('username')
        pwd = self.cleaned_data.get('password')
        if user and pwd:
            pass
        from django.core.exceptions import ValidationError
        # 1.不返回值,默认 self.cleaned_data
        # 2.返回值,self.cleaned_data=返回的值
        # 3.报错,ValidationError ->  self.add_error(None, e)
        # print(self.cleaned_data)
        # raise ValidationError("整xxxxx体错误")

    def _post_clean(self):
        pass


class SmsLoginForm(forms.Form):
    role = forms.ChoiceField(
        required=True,
        label='角色',
        choices=(('2', '客户'), ('1', '管理员')),
        widget=forms.Select(attrs={"class": "form-control"})
    )
    # <input type = "text" class ="form-control" placeholder="用户名" name="username" >
    mobile = forms.CharField(
        required=True,
        label='手机号',
        widget=forms.TextInput(attrs={"class": "form-control", "placeholder": "手机号"})
    )
    code = forms.CharField(
        required=True,
        label='短信验证码',
        widget=forms.PasswordInput(attrs={"class": "form-control", "placeholder": "短信验证码"})
    )


# return render(request, 'login.html')
def login(request):
    if request.method == "GET":
        form = LoginForm()
        return render(request, "login.html", {"form": form})

    # 1.接收并获取数据(数据格式或是否为空验证 - Form组件 & ModelForm组件)
    form = LoginForm(data=request.POST)
    if not form.is_valid():
        return render(request, "login.html", {"form": form})

    # 2.去数据库校验  1管理员  2客户
    data_dict = form.cleaned_data
    role = data_dict.pop('role')
    if role == "1":
        user_object = models.Administrator.objects.filter(active=1).filter(**data_dict).first()
    else:
        user_object = models.Customer.objects.filter(active=1).filter(**data_dict).first()

    # 2.1 校验失败
    if not user_object:
        form.add_error("username", "用户名或密码错误")
        return render(request, "login.html", {'form': form})

    # 2.2 校验成功,用户信息写入session+进入项目后台
    mapping = {"1": "ADMIN", "2": "CUSTOMER"}
    request.session['user_info'] = {'role': mapping[role], 'name': user_object.username, 'id': user_object.id}

    return redirect('/home/')

2.7.3

标签:forms,form,self,校验,class,Forms,组件,data,bug
From: https://www.cnblogs.com/Tmars/p/18449245

相关文章

  • Vue.js组件开发研究
    摘要随着前端技术的快速发展,Vue.js以其轻量级、高性能和组件化开发的优势,在前端开发领域占据了重要地位。本研究深入探讨了Vue.js组件开发的理论基础、开发方法以及实际应用。通过系统梳理Vue.js框架的核心特性、组件化思想及Vue.js组件的基本概念,本研究为Vue.js组件开发提供......
  • 【VMware VCF】使用 SFTP 服务器备份 VCF 核心组件的配置文件。
    可以定期对VMwareCloudFoundation环境中的相关核心组件(如SDDCManager、NSXManager以及vCenterServer等)创建配置备份,以防止当意外故障或数据丢失时,能够进行恢复。默认情况下,NSXManager组件的备份将创建并存储在SDDCManager设备中内置的SFTP服务器上,建议单独创建......
  • winforms基本操作-将datagridview内容保存为excel文件
    这里记录一下将winforms展示的datagridview,导出或保存为excel文件。这里说一下环境、版本信息:win系统:win11框架:winforms依赖:Microsoft.Office.Interop.Excel.net:8.0.401.netframework:4.8DataGridView对象为dataGridView1,然后添加一个按钮,绑定事件btnConfirm即可。priva......
  • bugku media(未解出)
    url:https://ctf.bugku.com/challenges/detail/id/573.html附件2个文件一个misc1.png一个key.wav 既然是key.wav一定隐藏了什么东西查看没看到什么东西misc1.png尾部有一段附加数据,不知道有什么用. RjAgOUYgOTkgODMgRjAgOUYgOTIgQjUgRjAgOUYgOEMgQkYgRjAgOUYgOEUgQTQg......
  • baby-mix bugku
    url: https://ctf.bugku.com/challenges/detail/id/571.html附件下载后,感觉是伪加密但是也能解压出来内容解压出来是:misc.png 看题目的提示,mix,果然misc.png混了一个二维码,扫描出来一串数字:4a5a4a584732544748424658515654514f4634575135435447564a4749564a5347463455......
  • 【VMware VCF】使用 SoS 实用程序检查 VCF 环境的运行状态以及收集相关组件的日志信息
    VMwareCloudFoundation解决方案中有一个叫SupportabilityandServiceability(VMwareCloudFoundationPart03:准备Excel参数表。”。同样,这个SoS程序也可以在SDDCManager虚拟机中使用,并且具有更多实用的功能,比如在VCF环境中运行状态检查以及收集相关组件的日志等,下......
  • 【VMware VCF】使用 SoS 实用程序检查 VCF 环境的运行状态以及收集组件的日志信息。
    VMwareCloudFoundation解决方案中有一个叫SupportabilityandServiceability(SoS)可支持性和可维护性的实用程序,可能你在初始构建VCF管理域的时候使用过这个工具,当时使用这个工具在VMwareCloudBuilder虚拟机中将用于部署的VCF管理域的Excel参数表转换为JSON格式的......
  • 记一次控件提升后,运行却不显示的Bug
    .h文件#ifndefVOLUMETOOLBTN_H#defineVOLUMETOOLBTN_H#include<QToolButton>#include<memory>classVolumeToolBtn:publicQToolButton{Q_OBJECTpublic:explicitVolumeToolBtn(QWidget*parent=nullptr);~VolumeToolBtn()override;......
  • Debuggers 1012:Introductory GDB
    OpenSecurityTraining2LearningPaths:VulnerabilityHunting&Exploitationpython:https://www.learnpython.org/路径图:https://ost2.fyi/OST2_LP_Vulns_Exploits.pdfDebuggers1012:IntroductoryGDB(与python)-->Architecture1001:x86-64Assembly-->R......
  • Vue.js 组件开发知识详解
    ✅作者简介:2022年博客新星第八。热爱国学的Java后端开发者,修心和技术同步精进。......