首页 > 其他分享 >Django Forms组件,展示用户输入不合规的提示信息,钩子函数

Django Forms组件,展示用户输入不合规的提示信息,钩子函数

时间:2024-03-25 09:12:13浏览次数:23  
标签:username forms form 校验 Django Forms length 提示信息 password

Django Forms组件,展示用户输入不合规的提示信息,钩子函数

前戏:使用form表单,用户输入特定信息,比如:金瓶,输入框右侧提示信息,不使用Ajax。

前端代码:

<body>
<form action="" method="post">
    <p>username: <input type="text" name="username">
        <!--get请求触发是,字典为空,span是行内标签,行内标签特性文本带下取决于内部文本,此时不占任何空间-->
        <span style="font-size: 15px">{{ back_dict.username }}</span>
    </p>

    <p>password: <input type="text" name="password">
        <span style="font-size: 15px">{{ back_dict.password }}</span>
    </p>

    <input type="submit" class="btn btn-danger">
</form>
</body>

后端代码逻辑:

def pl(request):
    back_dict = {'username': '', 'password': ''}
    """
    首先无论是POST还是GET请求,页面都可获得back_dict自定义字典
    只不过get请求来的时候,字典值是空的
    而post请求来之后,字典可能有值
    """
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if '金瓶' in username:
            back_dict['username'] = '违规用词'
        if len(password) < 3:
            back_dict['password'] = '密码不可低于三位数'
    return render(request, 'pl.html', locals())

以上使用到的技术点。

手动书写前端获取用户数据的html代码 ---渲染html代码
后端对用户数据进行校验 ---校验数据
对不符合要求的数据进行前端提示 ---展示提示信息
然而,form组件恰好也你能为我们做这些事。

注意: 数据校验前端可有可无,但是后端一定要有,前后端结合校验更好。

forms组件功能

  • 渲染html代码
  • 校验数据
  • 展示提示信息

forms基本使用

导入模块,并自定义类。

from django import forms

class MyForm(forms.Form):
    # username字段串类型最小3位,最大8位
    username = forms.CharField(min_length=3,max_length=8)
    # password字段串类型最小3位,最大8位
    password = forms.CharField(min_length=3,max_length=8)
    # 邮箱字段必须符合邮箱格式
    email = forms.EmailField()

校验数据

  1. 测试环境,test.py,自己拷贝代码准备
  2. Pycharm自带校验数据功能

方法 描述
.is_valid() 判断数据是否合法
.cleaned_data 查看校验通过数据
.errors 查看未通过数据以及未通过原因

froms组件校验数据只校验类中出现的字段,多传不影响,多传的字段直接忽略
form_obj = views.MyForm({'username':'junjie','password':'123','email':'[email protected]'})
form_obj.is_valid()
True
form_obj = views.MyForm({'username':'junjie','password':'123','email':'[email protected]','like':'play'})
form_obj.is_valid()
True
form_obj.cleaned_data
{'username': 'junjie', 'password': '123', 'email': '[email protected]'}
froms组件校验数据 默认情况下,类中的所有字段都必须传值。
form_obj = views.MyForm({'username':'junjie','password':'123'})
form_obj.is_valid()
False
form_obj.cleaned_data
{'username': 'junjie', 'password': '123'}
form_obj.errors
{'email': ['This field is required.']}

渲染html

forms组件只会自动渲染获取用户输入的标签(input,select,radio,checkbox)

第一种方式

封装程度太高,只适合本地测试使用。

views.py

from django import forms

class MyForm(forms.Form):
    # username字段串类型最小3位,最大8位
    username = forms.CharField(min_length=3,max_length=8)
    # password字段串类型最小3位,最大8位
    password = forms.CharField(min_length=3,max_length=8)
    # 邮箱字段必须符合邮箱格式
    email = forms.EmailField()


def index(request):
    # 先产生一个空对象,空对象是关键
    form_obj = MyForm()
    # 直接将该空对象传递给html页面
    return render(request,'index.html',locals())

前端

<form action="" method="post">
    <p>第一种渲染方式</p>
  <!--样式多,但是封装程度太高,适合本地测试-->
    {{ form_obj.as_p }}
		{{ form_obj.as_ul }}
    {{ form_obj.as_table }}
</form>


第二种方式

扩展性高,但是书写代码过多,一般不用

<form action="" method="post">
    <p>第二种渲染方式</p>
    <p>{{ form_obj.username.label }}: {{ form_obj.username }}</p>
    <p>{{ form_obj.password.label }}: {{ form_obj.password }}</p>
    <p>{{ form_obj.email }}: {{ form_obj.email.label }}</p>
</form>

第三种渲染方式,推荐使用

    <p>第三种渲染方式</p>
    {% for form in form_obj %}
        <p>{{ form.label }}: {{ form }}</p>
    {% endfor %}

    <p></p>


总结:label属性默认展示的是类中定义的字段首字母与大写的形式,也可以自己修改,直接给字段对象加label属性即可。

展示用户输入不合规的提示信息

浏览器会自动校验数据,但是前端的校验弱不禁风,检查中可以更改类型,那么如何让浏览器不做校验由后端来做校验?

<!--novalidate 告知前端不做校验-->
<form action="" method="post" novalidate>
</form>
![](/i/l/?n=24&i=blog/1223896/202403/1223896-20240325085401845-612882431.png)![](/i/l/?n=24&i=blog/1223896/202403/1223896-20240325085407801-64960124.png)
<!--novalidate 告知前端不做校验-->

<form action="" method="post" novalidate>
    <p>第三种渲染方式</p>
    {% for form in form_obj %}
        <p>{{ form.label }}: {{ form }}</p>
        <!--{{ form.errors.0 }} 意味着这拿列表中第一个错误信息,并且也不会生成ul标签-->
        <span style="color: red">{{ form.errors.0 }}</span>
    {% endfor %}
    <input type="submit" class="btn btn-danger">
</form>


此时input输入框最多输入也被限制,并且点击提交按钮,页面刷新但是input输入框中的信息也不会被刷新,原由还是form组件的特殊之处,那么为什么会如此?

查看后端逻辑代码。

def index(request):
    # 先产生一个空对象,空对象是关键
    form_obj = MyForm()
    if request.method == 'POST':
        # 获取用户数据并校验
        """
        1.数据获取繁琐
        2.校验数据需要构造成字典的格式传入才可以
        ps:但是request.POST 可以看成一个字典
        """
        form_obj = MyForm(request.POST)
        # 判断数据是否合法
        if form_obj.is_valid():
            # 合法操作数据库,存储数据
            return HttpResponse('恭喜,输入数据全都合规')
        # 不合法 有错误
        # else:
            # 如何将错误信息展示到前端?
    # 直接将该空对象传递给html页面
    return render(request, 'index.html', locals())

  • forms组件展示错物信息必备的条件:
  • get请求和post请求传给html页面的对象变量名必须一样
    forms组件当你的数据不合法的情况下,会保存上次输入的数据,让你基于之前的结果进行修改,更加人性化
    到此forms组件错误信息介绍完毕,接下补充知识。
    方法 描述
    label 字段名
    error_messages 自定义报错信息
    initial 默认值
    required forms组件中所有字段默认必填(required)
    required默认为Ture,可改为False
    控制字段是否必填
    widget 更改input的type类型,以及增加bootstrap样式
    ValidationError 正则校验,需要导入模块
    radio 单选框
    Select 下拉框
    checkbox 多选框
ValidationError,forms组件正则校验,自上而下校验。
from django.core.validators import RegexValidator

举例ValidationError:

phone = forms.CharField(
    validators=[
        RegexValidator(r'^[0-9]+$', '请输入数字'), # 先校验这个正则,通过再校验下面这个正则
        RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
    ]
)

后端逻辑代码error_messages:

from django import forms


class MyForm(forms.Form):
    # username字段串类型最小3位,最大8位
    username = forms.CharField(min_length=3, max_length=8, label='用户名',
                               # 不合符提醒自定义信息
                               error_messages={
                                   'min_length=3':'用户名最少3位',
                                   'max_length':'用户名最大8位',
                                   # required没有传值
                                   'required':'用户名不能为空'
                               })
    # password字段串类型最小3位,最大8位
    password = forms.CharField(min_length=3, max_length=8, label='密码',
                               error_messages={
                                   'min_length=3': '密码最少3位',
                                   'max_length': '密码最大8位',
                                   # required没有传值
                                   'required': '密码不能为空'
                               }
                               )
    # 邮箱字段必须符合邮箱格式
    email = forms.EmailField(label='邮箱',
                             error_messages={
                                 # 邮箱固定格式
                                 'invalid':'邮箱格式不能为空',
                                 # required没有传值
                                 'required': '邮箱不能为空'
                             }
                             )


def index(request):
    # 先产生一个空对象,空对象是关键
    form_obj = MyForm()
    if request.method == 'POST':
        # 获取用户数据并校验
        """
        1.数据获取繁琐
        2.校验数据需要构造成字典的格式传入才可以
        ps:但是request.POST 可以看成一个字典
        """
        form_obj = MyForm(request.POST)
        # 判断数据是否合法
        if form_obj.is_valid():
            # 合法操作数据库,存储数据
            return HttpResponse('恭喜,输入数据全都合规')
        # 不合法 有错误
        # else:
            # 如何将错误信息展示到前端?
    # 直接将该空对象传递给html页面

    return render(request, 'index.html', locals())


举例radio,select,checkbox

# radio 单选框
gender = forms.fields.ChoiceField(
    choices=((1, "男"), (2, "女"), (3, "保密")),
    label="性别",
    initial=3,
    widget=forms.widgets.RadioSelect()
)

# select 单选下拉框
hobby1 = forms.ChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
    label="爱好",
    initial=3,
    widget=forms.widgets.Select()
)

# select 多选下拉框
hobby2 = forms.MultipleChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=[1, 3],
    widget=forms.widgets.SelectMultiple()
)

# 单选checkbox
keep = forms.ChoiceField(
    label="是否记住密码",
    initial="checked",
    widget=forms.widgets.CheckboxInput()
)

# 多选checkbox
hobby = forms.MultipleChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=[1, 3],
    widget=forms.widgets.CheckboxSelectMultiple()
)

钩子函数(HOOK)

描述:在特点的节点自动触发完成响应操作。在forms组件中类似于第二道关卡,让我们自定义校验规则。

在forms组件中有两类钩子:

  • 局部钩子
    当你需要给单个字段增加校验规则的时候可以使用
  • 全局钩子
    当你需要给多个字段增加校验规则的时候可以使用
第一道forms校验通过会触发自定义钩子函数校验 ,在类中定义。

举例:

  1. 校验用户名中不能含有666 ---只校验一个字段,局部钩子
    2.校验密码和确认密码是否一致 ---校验多个字段,全局钩子
class MyForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=8, label='用户名',
                               error_messages={'min_length': '最小三位数',
                                               'max_length': '最大三位数',
                                               'required': '不能为空'})

    password = forms.CharField(min_length=3, max_length=8, label='密码',
                               error_messages={
                                   'min_length=3': '密码最少3位',
                                   'max_length': '密码最大8位',
                                   # required没有传值
                                   'required': '密码不能为空'
                               }
                               )

    two_password = forms.CharField(min_length=3, max_length=8, label='二次确认密码',
                                   error_messages={
                                       'min_length=3': '二次确认密码最少3位',
                                       'max_length': '二次确认密码最大8位',
                                       # required没有传值
                                       'required': '二次确认密码不能为空'
                                   }
                                   )

    email = forms.EmailField(label='邮箱',
                             error_messages={
                                 # 邮箱固定格式
                                 'invalid': '邮箱格式不能为空',
                                 # required没有传值
                                 'required': '邮箱不能为空'
                             }
                             )

    # 钩子函数
    # 局部钩子
    def clean_username(self):
        # 获取到用户名
        username = self.cleaned_data.get('username')
        if '666' in username:
            # 提示前端展示错误信息
            self.add_error('username', '不能只有666')
        # 将钩子函数勾出来的数据再放回去
        return username

    # 全局钩子
    def clean(self):
        password = self.cleaned_data.get('password')
        two_password = self.cleaned_data.get('two_password')
        if two_password != password:
            self.add_error('two_password','两次密码不一致')
        # 将钩子函数勾出来的数据再放回去
        return self.cleaned_data

标签:username,forms,form,校验,Django,Forms,length,提示信息,password
From: https://www.cnblogs.com/HeroZhang/p/18093657

相关文章

  • django脚本orm中使用原生sql
    fromdjango.core.management.baseimportBaseCommandfromchat_greeting_messages.modelsimportGreetingimportosfromdjango.dbimportconnectionclassCommand(BaseCommand):help="Patchinitializationrecruiternotsuitablegretting"......
  • 基于 HttpRunner + Django + Vue + Element UI 的接口自动化测试平台,生产可用
    LunarLink平台简介基于HttpRunner+Django+Vue+ElementUI的接口自动化测试平台,生产可用。此外,非常感谢花菜。没有AnotherFasterRunner就不会有LunarLink......
  • python趣味编程-使用 Django 和 WebSockets 的 Python 简单实时聊天室网站
    在Python中使用Django的简单实时聊天室系统该项目名为“简单实时聊天室系统”。这是一个使用Python和DjangoFramework开发的基于Web的应用程序。该应用程序是一个供随机用户使用的简单聊天室。所有人都可以在一个聊天框或对话框中进行交流。聊天消息会自动更新到所......
  • python趣味编程-使用 Django 的 Python 大学考勤管理系统
    在Python中使用Django的大学考勤管理系统该项目的名称为《大学考勤管理系统》。这是一个使用DjangoFramework用Python开发的基于Web的应用程序。该项目帮助某些大学学院存储/记录和管理学生每堂课的出勤情况。使用该应用程序,他们可以轻松列出班级学生名单并记录每......
  • django框架简介
    【一】python主流web框架//django大而全自带的功能非常的多但是有时候会略显笨重//flask小而精自带的功能非常的少但是第三方模块非常的多类似于'游骑兵'flask的第三方模块加到一起甚至比django还多并且也越来越像djangoflask由于过多的依赖于第三方模块有时候也......
  • django框架三板斧
    【一】Django项目如何添加新功能【1】添加URL映射在项目的urls.py中,通过导入相应的应用app的views在urlpatterns列表中添加对应的映射如fromdjango.contribimportadminfromdjango.urlsimportpathfromuserimportviewsurlpatterns=[path('admin/',admin......
  • Django - 配置Django-Debug-Toolbar
    配置Django-Debug-Toolbargithub:https://github.com/jazzband/django-debug-toolbar安装Django-Debug-Toolbarpipinstalldjango-debug-toolbar配置-修改settings.pyifDEBUG:MIDDLEWARE+=['debug_toolbar.middleware.DebugToolbarMiddleware',......
  • Python Django框架
    1、Django简介Python下有多款不同的Web框架,Django是最有代表性的一种。许多成功的网站和APP都基于Django。Django是一个开源的Web应用框架,由Python写成。Django采用了MVC的软件设计模式,即模型M,视图V和控制器C。Django本身基于MVC架构,即Model(模型)+View(视图)+Controller(控......
  • 创建Django项目
    安装相关的包pipinstalldjango创建流程项目目录移除模板位置,同时删除最外面的模板文件夹templates快速创建应用注册应用注册路由视图相关模板#静态资源{%loadstatic%}<linkrel="stylesheet"href="{%static'/css/font.css'%}"><scriptsrc="{%st......
  • 使用Django-Simple-Captcha在Django项目加入验证码模块并自定义样式
    在Django项目中加入验证码功能,通常需要借助第三方库,比如Django-Smple-Captch、Django-reCAPTCHA、DEF-reCAPTCHA、Wagtail-Django-ReCaptcha、Django-Friendly-Captcha等。其中,Django-Smple-Captcha是一个流行的选择,它提供了一个简单而强大的Django应用,无需调用第三方API,......