zoukankan      html  css  js  c++  java
  • day59

    多对多的三种创建方式

      1、全自动(推荐使用的**)

    优势:第三张可以任意的扩展字段

    缺点:ORM查询不方便,如果后续字段增加更改时不便添加修改

      manyToManyField创建的第三张表属于虚拟的,后缀会自动添加有_id的外键字段

    创建的方式:

    img

      2、纯手动(不推荐使用)

      需要手动创第三方表

    优势:第三张表可以任意的扩展字段

    缺点:ORM查询不便

    img

       3、半自动(推荐使用***)

    优势:结合了全自动和半自动的两个优点,把建表的关系直接在一张表上表示出来

    img

    这样创建的表,在多对多时不支持ORM的操作有以下几种:

    """
       多对多字段的
       add
       set
       remove
       clear不支持
       
    """
    

    Form组件

    forms组件功能

      1、校验功能:

    • 就是将form表单中的值在post请求发送到服务端时,服务端利用forms组件去检验是否符合规则
    • form表单中的name属性值要和自定义forms组件的字段一致。

      2、标签的渲染功能

      3、渲染错误的信息

      4、局部钩子,再次检验

    使用forms组件是实现注册功能

    简单的注册功能的版本:

      实现简单的校验功能。设置条件,在注册的时候进行有效的检验

    views.py

    from django.shortcuts import render,reverse,redirect,HttpResponse
    from django.core.exceptions import ValidationError
    
    # Create your views here.
    def login(request):
        errors = {'username':'','password':''}
        if request.method=='POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            if '黄赌毒' in username:
                errors['username'] = '属于违法,警惕'
            if len(password)<6:
                errors['password'] = '密码过短,不安全'
        return render(request,'login.html',locals())
    

    login.html:

      在提交的按钮,输入框中绑定提示的错误信息,校验的条件在后端进行

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    <form action="" method="post">
        <p>username:
            <input type="text" name="username">
            <span style="color: red">{{ errors.username }}</span>
        </p>
        <p>password:
            <input type="password" name="password">
            <span style="color: red">{{ errors.password }}</span>
        </p>
        <input type="submit">
    </form>
    </body>
    </html>
    

    总结:forms组件能够直接完成以下的三部分

      1.渲染前端页面
      2.校验数据是否合法
     3.展示错误信息

    forms组件的基本用法

    基本的校验规则:

      先写好一个继承了forms.Form的类

    from django import forms
    
    class LoginForm(forms.Form):
    username = forms.CharField(max_length=8,min_length=3)  # 用户名最长八位最短三位
    password = forms.CharField(max_length=8,min_length=5)  # 密码最长八位最短五位
    email = forms.EmailField()  # email必须是邮箱格式
    

    forms的校验规则:根据字段一个个进行比对,符合条件和错误的分别的保存起来

    img

    forms基本的使用

    1.将需要校验的数据,以字典的方式传递给自定义的类,实例化产生对象    form_obj = views.LoginForm({'username':'jason','password':'123','email':'123'})2.如何查看数据是否全部合法    form_obj.is_valid()  # 只有所有的数据都符合要求 才会是True      False3.如何查看错误原因    form_obj.errors    {    'password': ['Ensure this value has at least 5 characters (it has 3).'],     'email': ['Enter a valid email address.']    }4.如何查看通过校验的数据    form_obj.cleaned_data        {'username': 'jason'}直接在pycharm终端输入命令进行校验:
    
    
    

    注意事项:

    1.自定义类中所有的字段默认都是必须要传值的
    2.可以额外传入类中没有定义的字段名 forms组件不会去校验 也就意味着多传一点关系没有

    在书写的字段内;只能多传不能少传。

    img

    forms三种渲染方式

      书写from表单的三种方法:

    前端简单的from表单如下,原始的

    img

    在Django中利用forms组件书写的from表单又以下三种方法:

    先在后端开启路由向前端传递数据信息,views.py

    def register(request):
        # 先生成一个空白的自定义类对象
        form_obj = LoginForm()
        # 将该对象传递给前端
        return  render(requesr,'register.html')
    

    前端书写的register.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    <form action="" method='post' novalidate>
        <p>第一种渲染页面的方式(封装程度太高 一般只用于本地测试  通常不适用)</p>
        {{ form_obj.as_p }}
        {{ form_obj.as_ul }}
        {{ form_obj.as_table }}
    
        <p>第二种渲染页面的方式(可扩展性较高 书写麻烦)</p>
        <p>{{ form_obj.username.label }}{{ form_obj.username }}</p>
        <p>{{ form_obj.password.label }}{{ form_obj.password }}</p>
        <p>{{ form_obj.email.label }}{{ form_obj.email }}</p>
    
        <p>第三种渲染页面的方式(推荐)</p>
        {% for foo in form_obj %}
            <p>{{ foo.label }}:{{ foo }}
            <span>{{ foo.errors.0 }}</span>
            </p>
        {% endfor %}
        <input type="submit">
    
    </form>
    </body>
    </html>
    

    1、第一种渲染页面的方式(封装程度太高 一般只用于本地测试 通常不适

    img

    2、

    第二种渲染页面的方式(可扩展性较高 书写麻烦)

    img

    3、

    第三种渲染页面的方式(推荐)

    img

    forms组件展示错误的信息提示

    moldes.py,建表的时候指定校验的方式,和条件

    from django import forms
    from django.core.validators import RegexValidator
    from django.forms import widgets
    
    class LoginForm(forms.Form):
        username = forms.CharField(max_length=8,min_length=3,label='用户名',initial='tankdsb',
                                   error_messages={
                                       'max_length':'用户名最大八位',
                                       'min_length':'用户名最小三位',
                                       'required':'用户名不能为空'
                                   },widget=widgets.TextInput()
                                   )  # 用户名最长八位最短三位
        password = forms.CharField(max_length=8,min_length=5,label='密码',error_messages={
                                       'max_length':'密码最大八位',
                                       'min_length':'密码最小五位',
                                       'required':'密码不能为空'
                                   },
                                   widget=widgets.PasswordInput(attrs={'class':'form-control c1 c2','username':'jason'})
                                   )  # 密码最长八位最短五位
        confirm_password = forms.CharField(max_length=8, min_length=5, label='确认密码', error_messages={
            'max_length': '确认密码最大八位',
            'min_length': '确认密码最小五位',
            'required': '确认密码不能为空'
        }, required=False, validators=[RegexValidator(r'^[0-9]+$', '请输入数字'),
                                       RegexValidator(r'^159[0-9]+$', '数字必须以159开头')])  # 密码最长八位最短五位
        email = forms.EmailField(label='邮箱',error_messages={
            'required':'邮箱不能为空',
            'invalid':'邮箱格式不正确'
        })  # email必须是邮箱格式
    

    views.py

    def reg(request):
        # 1 现生成一个空的自定义类的对象
        form_obj = LoginForm()
        # 2 将该对象传递给前端页面
        if request.method == 'POST':
            # 3 获取前端post请求提交过来的数据
            # print(request.POST)  # 由于request.POST其实也是一个字典,所有可以直接传给LoginForm
            form_obj = LoginForm(request.POST)
            # 4 校验数据  让forms组件帮你去校验
            if form_obj.is_valid():
                # 5 如果数据全部通过 应该写入数据库
                pass
            # 6 如果不通过 一个像前端展示错误信息
        return render(request,'reg.html',locals())
    

    前端html

    img

    注意事项:

    1.forms组件在帮你渲染页面的时候,只会渲染获取用户输入的标签 ,提交按钮需要你手动添加
    2.input框的label注释 ,不指定的情况下,默认用的类中字段的首字母大写

    关键字:novalidate

      告诉前端取消掉自带的校验方式,form标签指定novalidate属性即可,让后端来书写

    img

    前端自带的校验方法:

    img

    字段的校验

    掌握的自定义字段,用正则表达式书写校验规则,手机号的验证:

      RegexValidator验证器

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

    自定义验证函数(了解)

    imgimg自定义的验证函数方法

    钩子函数(HOOK)

      就是forms组件暴漏给用户的,可以自定义额外的检验规则;必须写在Form类里面

    局部钩子

      我们在Fom类中定义 clean_字段名() 方法,就能够实现对特定字段进行校验。

    局部钩子(针对某一个字段做额外的校验) 校验用户名中不能包含666 一旦包含 提示

    def clean_username(self):
        username = self.cleand_data.get('username')
        if '666' in username:
            self.add_error('username','密码有危险提示,请从新修改哦')
            return username
    

    全局钩子函数

      全局钩子(针对多个字段做额外的校验) 校验用户两次密码是否一致

    有password和confirm_password两个字段:

    # 全局钩子(针对多个字段做额外的校验)    校验用户两次密码是否一致
        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
    

    forms组件其他字段及其他操作的使用

    """
    required
    是否必填
    label
    注释信息
    error_messages
    报错信息
    
    initial
    默认值
    
    widget
    控制标签属性和样式
    widget = widgets.PasswordInput()
    控制标签属性
    widget = widgets.PasswordInput(attrs={'class': 'form-control c1 c2', 'username': 'jason'})
    
    """多个类就空格格开书写:c2 c2
    

    img

    其他字段了解知识点(知道有这些对象 需要用到的时候 能够知道去哪找)

    # 单选的radio框
        gender = forms.ChoiceField(
            choices=((1, "男"), (2, "女"), (3, "保密")),
            label="性别",
            initial=3,
            widget=forms.widgets.RadioSelect()
        )
        # 单选select
        hobby = forms.ChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
            label="爱好",
            initial=3,
            widget=forms.widgets.Select()
        )
        # 多选的select框
        hobby1 = 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
        hobby2 = forms.MultipleChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
            label="爱好",
            initial=[1, 3],
            widget=forms.widgets.CheckboxSelectMultiple()
        )
    
        phone = forms.CharField(
            validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
        )
    

    具体的展示:

    img

    forms组件的源码分析

      通过源码解析,看Django内部的forms组件是如何是实现校验的原理的;大致了解

    img

    点击进去查看is_valid()方法

    img

    核心精髓实现功能的代码部分

    img

  • 相关阅读:
    弱爆程序员的特征值
    快捷渐变效果
    做事务性的发布数据库日志会越来越大
    判断MS SQLSERVER临时表是否存在
    SQLite实现加密
    CentOS6.4下安装TeamViewer8
    安装CDT
    CentOS中安装Courier New字体
    VS2012的Windows程序不显示DOS窗口
    log4cpp安装使用
  • 原文地址:https://www.cnblogs.com/xwjhyy/p/11980742.html
Copyright © 2011-2022 走看看