day57 forms校验性组件

多对多三种创建方式

1.全自动(一般情况下)

好处:
自始至终都没有操作第三种表,全部都是由orm自动创建的。
还内置了四个操作第三张表的方法。
不足:
自动创建的第三张表无法扩展修改字段,表的扩展性较差。

class Book(models.Model):
    title=models.CharField(max_length=32)
    #多对多关系字段
    author=models.ManyToManyField(to='Author')
    
class Author(models.Model):
    name=models.CharField(32)

2.纯手撸(了解)

好处:
第三张表字段个数和字段名称全都可以自己定义
不足:
不再支持orm跨表查询(add,remove,set,clear),不再有正反向的概念

class Book(models.Model):
    title=models.CharField(max_length=32)
    
class Author(models.Model):
    name=models.CharField(32)    
    
class Book2Author(models.Model):
    book=models.ForeignKey(to='Book')
    author=models.ForeignKey(to='Author')
    create_time=models.DateField(auto_now_add=True)    

3.半自动(推荐使用)

好处:
可以任意的添加和修改第三张表中的字段,并且支持orm跨表查询
不足:
不支持内置的四个方法(add,remove,set,clear)

class Book(models.Model):
    title=models.CharField(max_length=32)
    #多对多关系字段
    author=models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author'))
    '''through_fields:在那张表中,那个字段就放在前面
    当你的ManyToManyField只有一个参数to的情况下,orm会自动创建第三张表
    如果加入了through和through_fields那么orm就不会自动帮你创建第三张表,
    但是他会在内部维持关系,可以继续使用跨表查询,
    through 自己指定第三张关系表
    through_fields 自己指定第三张关系表 到底哪两个字段维护着表与表之间的多对多关系,'''
class Author(models.Model):
    name=models.CharField(32)

class Book2Author(models.Model):
    book=models.ForeignKey(to='Book')
    author=models.ForeignKey(to='Author')
    create_time=models.DateField(auto_now_add=True)
    #该表中可以有任意多的外键字段,可以扩展任意的字段

forms校验性组件

需求:
1.写一个注册页面,获取用户输入的用户名和密码提交到后端之后,后端需要对用户名和密码做校验。不符合的展示对应的错误信息。

将数据传递给后端做数据校验 》》》检验数据
手动书写html代码获取用户输入》》》渲染标签
如果数据错误,展示错误信息 》》》展示信息

forms组件:
能够做的事情就是上面的三步
渲染标签 检验数据 展示信息

使用forms组件的前提是:提前写好一个类

# 使用forms组件的第一步,必须先写一个类
from django import forms

class MyForm(forms.Form):
    # username字段 最少三位 最多八位
    username = forms.CharField(max_length=8, min_length=3)
    # password字段 最少三位 最多八位
    password = forms.CharField(max_length=8, min_length=3)
    # email字段 必须是邮箱格式
    email=forms.EmailField()

校验数据

# 点击python console
from app02 import views
#1.给写好的类传字典数据(待校验的数据)
form_obj=views.MyForm({'username':'jason','password':'12','email':'123'})

#2.如何查看校验的数据是否合法
form_obj.is_valid()
Out[4]: False # 只有数据全部符合校验规则的情况下,结果才是True,否则都为False
    
#3.如何查看不符合规则的字段及错误的理由
form_obj.errors
Out[5]: 
{'password': ['Ensure this value has at least 3 characters (it has 2).'],
 'email': ['Enter a valid email address.']}

# 4.如何查看符合校验规则的数据
form_obj.cleaned_data
Out[6]: {'username': 'jason'}
    
# 5.forms组件中,定义的字段默认都是必须要传值的,不能少传
form_obj=views.MyForm({'username':'jason','password':'123'})
form_obj.is_valid()
Out[8]: False
form_obj.errors
Out[10]: {'email': ['This field is required.']}

# 6.forms组件只会校验forms类中定义的字段,如果多传了,不会有任何影响
form_obj=views.MyForm({'username':'jason','password':'1234','email':'[email protected]','xxx':'jjkj'})
form_obj.is_valid()
Out[13]: True

渲染标签

forms组件只会帮你渲染获取用户输入的标签,不会帮你渲染提交按钮,需要手动添加

视图层:

def indexx(request):
    #渲染标签 第一步 需要生成一个空的forms类的对象
    form_obj=MyForm()
    #直接将生成得对象,传递给前端页面
    return render(request,'indexx.html',locals())

前端:

<p>forms组件渲染标签方式一:封装程度太高,不推荐使用,但是可以用在本地测试</p>
{{ form_obj.as_p }}
{{ form_obj.as_ul }}
{{ form_obj.as_table }}

<p>forms组件渲染标签方式二:不推荐使用,写起来太麻烦</p>
{{ form_obj.username.label }}{{ form_obj.username }}
{{ form_obj.password.label }}{{ form_obj.password }}
{{ form_obj.email.label }}{{ form_obj.email }}

<p>forms组件渲染标签方式三:推荐使用</p>
{% for forms in form_obj %}
    <p>
        {{ forms.label }}{{ forms }}
    </p>
{% endfor %}

如何将lable该成中文:在定义类得时候,给每个字段添加lable属性

class MyForm(forms.Form):
    # username字段 最少三位 最多八位
    username = forms.CharField(max_length=8, min_length=3,label='用户名')
    # password字段 最少三位 最多八位
    password = forms.CharField(max_length=8, min_length=3,label='密码')
    # email字段 必须是邮箱格式
    email=forms.EmailField(label='邮箱')

展示信息

数据的校验通常前后端都必须有,但前端的校验可有可无,并且弱不禁风。后端的校验必须要有,并且必须非常的全面。

如何告诉浏览器不做校验,form表单中加一个novalidate参数即可

如何报错信息为中文,在MyForm类里字段里加error_message属性

视图层:

from django import forms

class MyForm(forms.Form):
    # username字段 最少三位 最多八位
    username = forms.CharField(max_length=8, min_length=3,label='用户名',
                               error_messages={
                                   'max_length':'用户名最长为八位',
                                   'min_length':'用户名最短为三位',
                                   'required':'用户名不能为空'
                               })
    # password字段 最少三位 最多八位
    password = forms.CharField(max_length=8, min_length=3,label='密码',
                               error_messages={
                                   'max_length': '用户名最长为八位',
                                   'min_length': '用户名最短为三位',
                                   'required': '用户名不能为空'
                               })
    # email字段 必须是邮箱格式
    email=forms.EmailField(label='邮箱',
                           error_messages={
                               'required':'邮箱不能为空',
                               'invalid':'邮箱格式错误'
                           })


def indexx(request):
    #渲染标签 第一步 需要生成一个空的forms类的对象
    form_obj=MyForm()
    if request.method=='POST':
        #获取用户得数据 request.POST中  forms组件校验数据
        form_obj=MyForm(request.POST)#该变量名一定要跟上面的form_obj变量名一致
        if form_obj.is_valid():#研就forms组件入口就是
            print(form_obj.cleaned_data)
            return HttpResponse('数据全部OK')
        else:
            print(form_obj.errors)
    #直接将生成得对象,传递给前端页面
    return render(request,'indexx.html',locals())

前端:

<p>forms组件渲染标签方式三:推荐使用</p>
<form action="" method="post" novalidate>
    {% for forms in form_obj %}
        <p>
            {{ forms.label }}{{ forms }}
            <span>{{ forms.errors.0 }}</span>
        </p><!--form等价与方式二中对象点字段名-->
    {% endfor %}
    <input type="submit">
</form>
</body>
</html>

校验数据的方式:

内置的校验器

在MyForm类里字段里加validators属性

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

钩子函数 HOOK

当你觉得上面的所有的校验还是不能满足你的需求,你可以考虑使用钩子函数
是一个函数,函数体内你可以写任意的校验代码。在MyForm类里写

局部钩子

校验单个字段

    def clean_username(self):
        username=self.cleaned_data.get('username')
        if '666' in username:
            #给username所对应的框展示错误信息
            self.add_error('username','光喊666是不行的')
        return username
全局钩子

校验多个字段

    def clean(self):
        password=self.cleaned_data.get('password')
        confirm_password=self.cleaned_data.get('confirm_password')
        if not password==confirm_password:
            self.add_error('confirm_password','两次密码不一致')
        return self.cleaned_data

其他字段及参数

lable input框对应的提示信息
initial inout框默认值
required 默认为True控制字段是否必填

    username = forms.CharField(max_length=8, min_length=3,label='用户名',initial='jason',required=False,
     error_messages={
         'max_length':'用户名最长为八位',
         'min_length':'用户名最短为三位',
         'required':'用户名不能为空'
     })

widget 给input框设置样式及属性 在MyForm类里字段里加widget属性

from django.forms import widgets
widget=forms.widgets.TextInput({'class':'form-control c1 c2','username':'jason'})#添加了属性
widget=forms.widgets.PasswordInput()#input框变成了密文框

其他的标签在MyForm类书写

django settings源码

猜你喜欢

转载自www.cnblogs.com/zqfzqf/p/11979988.html