forms组件

内容概要

  • forms组件渲染标签
  • forms组件展示信息
  • forms组件校验补充
  • forms组件参数补充
  • forms组件源码剖析
  • modelform组件
  • django中间件

forms组件渲染标签

后端

class MyForm(forms.Form):
    username = forms.CharField(min_length=2, max_length=8)
    age = forms.IntegerField(min_value=0, max_value=200)
    email = forms.EmailField()

def ad_index_func(request):
    form_obj = MyForm()

    return render(request, 'indexPage.html', locals())
{# 方式一#}
    <p>{{ form_obj.as_p }}</p>

{{ form_obj.as_table }}
<p></p>
{{ form_obj.as_ul }}

优势 :全自动 简单粗暴

劣势:封装程度太高了 扩展性差 主要用于测试

{#方式二#}
    {{ form_obj.username.label }}
    {{ form_obj.username }}
    {{ form_obj.age.label }}
    {{ form_obj.age }}
    {{ form_obj.email.label }}
    {{ form_obj.email }}

优势:扩展性强,

劣势:太繁琐了

{#方式三#}
    {% for foo in form_obj %}
        {{ foo.label }}
        {{ foo }}

    {% endfor %}

封装程度较高 扩展性高 编写简单 推荐使用

注意事项

forms组件只负责渲染获取用户数据的便签 也就意味着form标签与按钮都需要自己写

<form action="" method="post">
    {% for foo in form_obj %}
        <p>{{ foo.label }}
        {{ foo }}</p>

    {% endfor %}
    <input type="submit" name="" id="">
</form>

前端校验是弱不禁风的 最终都需要后端来校验所以我们在使用forms组件的时候可以直接取消前端帮我们的校验

<form novalidate></form>

forms组件展示信息

后端不同请求返回的forms对象一定要是相同的变量名

<form action="" method="post" novalidate>
    {% for foo in form_obj %}
        <p>{{ foo.label }}
        {{ foo }}
        {{ foo.errors.0 }}</p>

    {% endfor %}
    <input type="submit" name="" id="">
</form>
def ad_index_func(request):
    # 产生一个空对象
    form_obj = MyForm()
    if request.method == "POST":
        # request.POST 可以看成一个字典
        # 所以可以把这个 request.POST直接放到 forms产生的类里面
        form_obj = MyForm(request.POST)
    return render(request, 'indexPage.html', locals())

针对错误的提示信息可以修改为各国语言

方式1 自定义内容

​ 给字段对象添加errors_messages参数

username = forms.CharField(min_length=2, max_length=8,
                           error_messages={'min_length': '最少为两个字符',
                                           'max_length': '最多为八个字符',
                                           'required': '用户输入不能为空'})  # 为空的报错

方式2:修改系统语言环境

这个global_settings是我们配置文件settings它爹

forms组件校验补充

forms组件针对字段数据的校验 提供了三种类型的校验方式(三种可以一起使用)

第一种类型:直接写参数

max_length

第二种类型:使用正则表达式

validators

    from django.core.validators import RegexValidator
    user = forms.CharField(
        validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
    )

第三种类型: 钩子函数

编写代码

自定义校验规则

局部函数

class MyForm(forms.Form):
    from django.core.validators import RegexValidator
    user = forms.CharField(min_length=2, max_length=8)

    age = forms.IntegerField(min_value=0, max_value=200, label='年龄')
    email = forms.EmailField(label='邮箱')

    # 钩子函数>>>:校验的最后一个环 是在字段所有的校验参数之后触发
    # 局部钩子>>>:每次只校验一个字段数据校验用户名是否存在
    def clean_user(self):
        # 获取前端的 user 传过来的数据
        user = self.cleaned_data.get('user')
        # 进行比对 如果是 jason    # 钩子函数>>>:校验的最后一个环 是在字段所有的校验参数之后触发
    def clean_user(self):
        # 获取前端的 user 传过来的数据
        user = self.cleaned_data.get('user')
        # 进行比对 如果是 jason
        if user == 'jason':
            # 就添加一个给 errors的字典里 'user': '用户吗jason已存在'
            # 
            self.add_error('user', '用户名jason已存在')
        return user
        if user == 'jason':
            # 就添加一个 'user': '用户吗jason已存在'
            self.add_error('user', '用户名jason已存在')
        return user
 

全局钩子

 # 全局钩子:一次可以校验多个字段数据     校验两次密码是否一致
def clean(self):
    password = self.cleaned_data.get('password')
    re_pass = self.cleaned_data.get('re_pass')
    if not password == re_pass:
        self.add_error('re_pass', '两次密码不一致')
    return self.cleaned_data

记得勾出来什么就得 返回什么

全局钩子是把全部的数据都钩出来,不管你用不用你都得把数据全部返回出去

forms组件参数补充

min_length        最小字符
max_length        最大字符
min_value         最小值
max_value         最大值
label           字段注释
error_messages     错误提示
validators         正则校验器
initial           默认值
required          是否必填
widget            控制标签的各项属性


widget用法

  from django.forms import widgets
    password = forms.IntegerField(label='密码',
                                  widget=forms.PasswordInput(attrs={'class': 'form_control'}))

forms组件源码剖析

切入口是: form_obj.is_valid()

先看 self.is_bound是什么玩意

去看看 self._errors

去看看 self.full_clean做了什么事

这三个函数

这是第一个

我们去看第二个

第三个

medelform组件

"""
我们学习校验组件的目的 绝大部分是为了数据录入数据库之前的各项审核

forms组件使用的时候需要对照模型类编写代码 不够方便
"""

forms组件的强化版本 更好用更简单更方便

models 层

class UserInfo(models.Model):
	username = models.CharField(max_length=32, verbose_name='用户名')
    age = models.IntegerField(verbose_name='年龄')

view

from django import forms
from app01 import models


class MyModelForm(forms.ModelForm):
    class Meta:
        model = models.UserInfo
        fields = '__all__'
        labels = {'username': '用户名'}


def ad_index_func(request):
    modelform_obj = MyModelForm()
    if request.method == 'POST':
        modelform_obj = MyModelForm(request.POST)
        if modelform_obj.is_valid():
            """
            这个save 就相当于 models.UserInfo.objects.create()
            或
            models.UserInfo.objects.update()
            """
            modelform_obj.save()
        else:
            print(modelform_obj.errors)

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

<form action="" method="post" novalidate>
    {% for foo in modelform_obj %}
        <p>{{ foo.label }}
        {{ foo }}
        {{ foo.errors.0 }}</p>

    {% endfor %}
    <input type="submit" name="" id="">
</form>

会把 表中的字段自动创建出来

posted @ 2022-12-21 20:12  可否  阅读(20)  评论(0编辑  收藏  举报