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':'[email protected]','xxx':'嘿嘿嘿'}
    )
form_obj.is_valid()
True

渲染标签

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

渲染标签方式1:

封装程度态高 不推荐使用 但是可以用在本地测试

{{ form_obj.as_p }}  
{{ 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 %}

{{ form.label }}{{ form }}

{% endfor %}

展示信息

{% for forms in form_obj %}

{{ forms.label }}{{ forms }} {{ forms.errors.0 }}

{% endfor %}

注意:

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

如何告诉浏览器不做校验 form表单中加一个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组件 要点)