FORM组件 要点
Posted allenchen168
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FORM组件 要点相关的知识,希望对你有一定的参考价值。
多对多三种创建方式
1、全自动创建
class Book(models.Model):
title = models.CharField(max_length=32)
# 多对多关系字段
authors = models.ManyToManyField(to='Authors')
class Authors(models.Model):
name = models.CharField(max_length=32)
好处:至始至终不用操作第三张表,全都是由ORM自动创建
? 内置的第三张表的方法:add、remove、set、clear
缺点:第三张表是自动创建的,无法扩展字段,扩展性差
2、纯手撸
class Book(models.Model):
title = models.CharField(max_length=32)
class Authors(models.Model):
name = models.CharField(max_length=32)
class Book2Authors(models.Model):
book = models.ForeignKey(to="Book")
author = models.ForeignKey(to="Authors")
create_time = models.DateField(auto_now_add = True)
优点:第三张表中字段个数和字段名称全都可以自己定义
缺点:不再支持orm跨表查询 不再有正反向的概念
? 内置的方法也是:add、remove、set、clear
3、半自动
class Book(models.Model):
title = models.CharField(max_length=32)
# 多对多关系字段
authors = models.ManyToManyField(
to='Authors',through='Book2Author',through_fields=("book","authors"))
"""
当 ManyToManyField 只有一个参数to的情况下 orm会自动创建第三张表
如果加了through和through_fields那么orm就不会自动创建第三张表 但是它会在内部自动维护关系 让你能够继续使用orm的跨表查询
through 自己指定第三张关系表
through_fields 自己指定第三张关系表中 到底哪两个字段维护者表与表之间的多对多关系
"""
class Authors(models.Model):
name = models.CharField(max_length=32)
# 多对多关系字段 等价
books = models.ManyToManyField(
to='Book', through='Book2Author', through_fields=("authors","book"))
class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
authors = models.ForeignKey(to='Authors')
"""
该表中可以有任意多的外键字段
可以扩展任意多字段
"""
优点:可以任意的添加和修改第三张表中的字段
并且支持orm跨表查询
缺点:不支持内置的方法:add、remove、set、clear
Forms组件
form组件的作用:
1、生成页面可用的html标签 --> 渲染标签
2、对用户提交的数据进行校验 --> 校验数据
3、保留已输入的合法的内容 --> 展示信息
使用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()
校验数据
# 1.给写好的类 传字典数据(待校验的数据)
form_obj = views.MyForm({'username':'jason','password':'12','email':'123'})
# 2.如何查看校验的数据是否合法
form_obj.is_valid()
False # 只有当你的数据全部符合校验规则的情况下 结果才是True 否则都为False
# 3.如何查看不符合规则的字段及错误的理由
form_obj.errors {
'password': ['Ensure this value has at least 3 characters (it has 2).'],
'email': ['Enter a valid email address.']
}
# 4.如何查看符合校验规则的数据
form_obj.cleaned_data {'username': 'jason'}
# 5.forms组件中 定义的字段默认都是必须传值的 不能少传
form_obj = views.MyForm({'username':'jason','password':'12345'})
form_obj.is_valid()
False
form_obj.errors{'email': ['This field is required.']}
# 6.forms组件只会校验forms类中定义的字段 如果你多传了 不会有任何影响
form_obj =views.MyForm(
{'username':'jason','password':'12345','email':'123@qq.com','xxx':'嘿嘿嘿'}
)
form_obj.is_valid()
True
渲染标签
forms组件只会帮你渲染获取用户输入的标签 不会帮你渲染提交按钮 需要你自己手动添加
渲染标签方式1:
封装程度态高 不推荐使用 但是可以用在本地测试
{{ form_obj.as_p }} <!--自动渲染所有input框 -->
{{ form_obj.as_ul }}
{{ form_obj.as_table }}
渲染标签方式2:
不推荐使用 写起来太烦了
{{ form_obj.username.label }}{{ form_obj.username }}
{{ form_obj.username.label }}{{ form_obj.password }}
{{ form_obj.username.label }}{{ form_obj.email }}
渲染标签方式3:推荐使用
{% for form in form_obj %}
<p>{{ form.label }}{{ form }}</p> <!--form 等价于你方式2中的对象点字段名-->
{% endfor %}
展示信息
<form action="" method="post" novalidate>
{% for forms in form_obj %}
<p>
{{ forms.label }}{{ forms }}
<span>{{ forms.errors.0 }}</span>
</p> <!--form 等价于你方式2中的对象点字段名-->
{% endfor %}
<input type="submit">
</form>
注意:
数据的校验通常前后端都必须有
但是前端的校验可有可无 并且弱不禁风
后端的校验必须要有 并且必须非常的全面
如何告诉浏览器不做校验 form表单中加一个novalidate参数即可
<form action="" method="post" novalidate>
校验数据的方式:
内置校验器:
一般来说,你需要用到的正则匹配规则,在网上都能找到,不要重复造轮子
from django.core.validators import RegexValidator
validators=[
RegexValidator(r'^[0-9]+$', '请输入数字'),
RegexValidator(r'^159[0-9]+$', '数字必须以159开头'),
]
钩子函数:
当你觉得上面的所有的校验还不能够满足你的需求 你可以考虑使用钩子函数
钩子函数是一个函数 函数体内你可以写任意的校验代码
分为局部钩子和全局钩子。
局部钩子: 用于校验单个字段
# 校验用户名中不能含有666 局部钩子
def clean_username(self):
username = self.cleaned_data.get('username')
if '666' in username:
# 给username所对应的框展示错误信息
# self.add_error('username','光喊666是不行的')
raise ValidationError('到底对不对啊')
# 将username数据返回
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
补充知识:其他字段
label input对应的提示信息
initial input框默认值
required 默认为True控制字段是否必填
widget 给input框设置样式及属性
widget=forms.widgets.TextInput({'class':'form-control c1 c2','username':'jason'})
widget=forms.widgets.TextInput(attrs={'class':'form-control c1 c2','username':'jason'})
以上是关于FORM组件 要点的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot中表单提交报错“Content type ‘application/x-www-form-urlencoded;charset=UTF-8‘ not supported“(代码片段