多对多三种创建方式

# 补充知识点 related_name 参数 正反向查询的name
publish = models.ForeignKey(to='Book', related_name='pb')
# 这样查publish表的时候就可以直接点pb了

全自动

 class Book(models.Model):
        title = models.CharField(max_length=255)
        # 多对多关系字段
        authors = models.ManyToManyField(to='Authors')

 class Authors(models.Model):
        name = models.CharField(max_length=32)

​ 好处:自始至终都没有操作第三张表 全部都是orm自动帮你创建的 且内置 4个方法 操作第三张表 add set remove clear

​ 不足: 自动创建的第三张表 无法扩展 和 字段修改 扩展性较差

全手动

 class Book(models.Model):
        title = models.CharField(max_length=255)

 class Authors(models.Model):
        name = models.CharField(max_length=32)

 class Book2Author(models.Model):
        book = models.ForeignKey(to='Book')
        author = models.ForeignKey(to='Authors')
        # 添加其他字段
        create_time = models.DateField(auto_now_add=True)

​ 好处:第三张表中字段完全可以自定义

​ 坏处:不在支持orm的跨表查询 以及内置的方法

半自动

class Book(models.Model):
        title = models.CharField(max_length=255)
        # 添加多对多关系字段
        authors = models.ManyToMangField(to='Authors', through='Book2Author', through_fields=('book','authors'))
        # through 告诉orm 用我自己建的外键

 class Authors(models.Model):
        name = models.CharField(max_length=32)

 class Book2Author(models.Model):
        book = models.ForeignKey(to='Book')
        author = models.ForeignKey(to='Authors')
        # 添加其他字段
        create_time = models.DateField(auto_now_add=True)
        # 该表中可以有任意多的外键字段

​ 当你的ManyToManyField只有一个参数to的情况下 orm会自动帮你创建第三张表

​ 如果你加了throughthrough_fields那么 orm就不会 帮你创建第三张表, 但是他会在内部帮你维护关系,让你能够使用orm的跨表查询

though_fields = ('book','author') 内的字段是有顺序的 在那张表就用那个字段 或者 去第三张表 看 第三张表查当前表通过那个字段 就是那个字段

through 是告诉django的orm 多对多对应关系是通过Book2Author来记录的

优点: 结合了 全自动全手动的 两个优点

form组件

​ 我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.。Django form组件就实现了上面所述的功能。


1.前端搭建页面 >>> 渲染页面
2.将数据传输后端处理 >>> 数据校验
3.展示错误信息 >>> 展示信息

基本使用

​ 提示:注意参数 required不能为空 默认是True
initial 默认值 label 标签名 invalid 无效的(格式) error_messages 校验错误的提示信息
widget 后跟forms.widget.字段类型 括号内的attr 是添加属性的

# form组件模块导入
from django import forms
# 自定义form类 继承forms.Form
class MyForm(forms.Form):
    # 定义需要校验和前端展示的标签或字段
    username = forms.CharField(max_length=8, min_length=3, label='用户名', required=True,
                               initial='输入....',
                               error_messages={
                                   'max_length':'最大8位',
                                   'min_length':'最小3位',
                                   'required':'不能为空',
                               },
                               widget=forms.widgets.TextInput(attrs={'class':'you is sd'})
                               )
    password = forms.CharField(max_length=16, min_length=5, label='密码', required=True,
                               initial='输入密码.....',
                               error_messages={
                                   'max_length':'最大16位',
                                   'min_length':'最小3位',
                                   'required':'不能为空',
                               },
                               widget=forms.widgets.PasswordInput(attrs={'class':'password'})
                               )
    email = forms.EmailField(label='邮箱',error_messages={
        'required':'不能为空',
        'invalid':'格式不正确'
    })

form_obj 及 is_valid()

def form(request):
    # 生成MyForm对象
    form_obj = MyForm()
    # 判断是否是post请求
    if request.method == 'POST':
        form_obj = MyForm(request.POST)
        # 判断数据是否通过校验
        if form_obj.is_valid():
            print('校验成功')
            return HttpResponse('校验成功')
        else:
            return render(request, 'test.html', locals())
    return render(request, 'test.html', locals())

前端渲染方式

{# 方式一 #}
    {{ form_obj.as_p }}
    {{ form_obj.as_ul }}
    {{ form_obj.as_table }}
{# 方式二 #}
    <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>
{# 方式三 #}   {# 推荐使用 #}
{# 使用对象点errors.0 拿到校验错误信息#}
    {% for foo in form_obj %}
        <p>{{ foo.label }}:{{ foo }}<span>{{ foo.errors.0 }}</span></p>
    {% endfor %}

取消前端自动校验

校验数据的时候可以前后端都校验 做一个双重的校验 但是前端的校验可有可无 而后端的校验则必须要有,因为前端的校验可以通过爬虫直接避开 前端取消浏览器校验功能 form标签指定novalidate属性即可

正则校验

# 导入模块
from django.core.validators import RegexValidator
# 例子
phone = forms.CharField(required=False,
                       validators=[RegexValidator(r'^[0-9]+$', '请输入数字'),
                                  RegexValidator(r'^159[0-9]+$', '数字必须是159开头')]
                       )

钩子函数(Hook方法)

forms组件暴露给用户可自定义的校验规则 需要在类中写(顺序是先通过普通校验 然后才是钩子)

cleaned_data

​ 校验通过的数据都会放在cleaned_data里面

主动抛错误信息

add_error() 两个参数 第一个是错误的字段 第二个是 错误的信息

from django.core.exceptions import ValidationError
raise ValidationError('手机格式错误')

局部钩子

​ 针对某一个字段做额外的校验 校验用户名字是否含有 666 一旦有 就提示

# 局部钩子固定写法 clean_ + 需要校验的字段
def clean_username(self):
    username = self.cleaned_data.get('username')
    if '666' in username:
        # 主动抛错误信息
        self.add_error('username', '名字中没有666')
    # 需要返回 username
    return username

全局钩子

​ 针对多个字段做额外的校验

# 局部钩子固定写法 clean
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

多选框(了解知识点)

radioSelect

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三",
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
        }
    )
    pwd = forms.CharField(min_length=6, label="密码")
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        initial=3,
        widget=forms.widgets.RadioSelect()
    )

单选Select

class LoginForm(forms.Form):
    ...
    hobby = forms.ChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=3,
        widget=forms.widgets.Select()
    )

多选Select

class LoginForm(forms.Form):
    ...
    hobby = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )

单选checkbox

class LoginForm(forms.Form):
    ...
    keep = forms.ChoiceField(
        label="是否记住密码",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )

多选checkbox

class LoginForm(forms.Form):
    ...
    hobby = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )

django----多对多三种创建方式 form组件的更多相关文章

  1. 多对多三种创建方式、forms组件、cookies与session

    多对多三种创建方式.forms组件.cookies与session 一.多对多三种创建方式 1.全自动 # 优势:不需要你手动创建第三张表 # 不足:由于第三张表不是你手动创建的,也就意味着第三张表字 ...

  2. Django-多对多关系的三种创建方式-forms组件使用-cookie与session-08

    目录 表模型类多对多关系的三种创建方式 django forms 组件 登录功能手写推理过程 整段代码可以放过来 forms 组件使用 forms 后端定义规则并校验结果 forms 前端渲染标签组件 ...

  3. ORM中choices参数(重要)、MTV于MVC模型、多对多关系三种创建方式

    choices参数(重要) **使用方式

  4. Django框架(十)--ORM多对多关联关系三种创建方式、form组件

    多对多的三种创建方式 1.全自动(就是平常我们创建表多对多关系的方式) class Book(models.Model): title = models.CharField(max_length=32 ...

  5. Django多对多表的三种创建方式,MTV与MVC概念

    MTV与MVC MTV模型(django): M:模型层(models.py) T:templates V:views MVC模型: M:模型层(models.py) V:视图层(views.py) ...

  6. 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)

    摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...

  7. 多对多的三种创建方式-forms相关组件-钩子函数-cookie与session

    多对多的三种创建方式 1.全自动(推荐使用的**) 优势:第三张可以任意的扩展字段 缺点:ORM查询不方便,如果后续字段增加更改时不便添加修改 manyToManyField创建的第三张表属于虚拟的, ...

  8. Struts2之命名空间与Action的三种创建方式

    看到上面的标题,相信大家已经知道我们接下来要探讨的知识了,一共两点:1.package命名空间设置:2.三种Action的创建方式.下面我们开始本篇的内容: 首先我们聊一聊命名空间的知识,namesp ...

  9. JavaScript 闭包的详细分享(三种创建方式)(附小实例)

    JavaScript闭包的详细理解 一.原理:闭包函数--指有权访问私有函数里面的变量和对象还有方法等:通俗的讲就是突破私有函数的作用域,让函数外面能够使用函数里面的变量及方法. 1.第一种创建方式 ...

随机推荐

  1. 反汇编分析objc函数枢纽objc_msgSend

    在分析objc_msgSend之前,先来搞清楚另一个问题. 函数是什么?可能会答 void foo(void) {} 像这样就是一个函数.或者函数包括函数原型和函数定义,是一段执行某样功能的机器代码. ...

  2. 小白学习React官方文档看不懂怎么办?2.JSX语法

      接下来我们就要讲到JSX语法了,在我们讲它之前,我们先引入一个概念叫语法糖.     听到这个名字首先我们可能会想到一个词叫”糖衣炮弹“,那么什么叫糖衣炮弹呢,就是给你说各种好听的话,来迷惑你,但 ...

  3. Python 编程语言要掌握的技能之一:使用数字与字符串的技巧

    最佳实践 1. 少写数字字面量 “数字字面量(integer literal)” 是指那些直接出现在代码里的数字.它们分布在代码里的各个角落,比如代码 del users[0] 里的 0 就是一个数字 ...

  4. Django安装和使用---python(3)

    一.安装 一般使用cmd 安装就可以 pip install django // 这是最新版本 pip install django==2.0.2(自定义安装2.0.2版本) 手动安装通过下载方式 d ...

  5. 关于Java运行机制

    目录 编译型语言与解释型语言的区别 编译型语言 解释型语言 细数两者之差别 Java的奇怪之处 Java的编译 Java的解释 具体机制 Java既是编译型语言,也是解释型语言. 首先先查找关于两种语 ...

  6. Windows Server 2008 服务器重启后卡死在Windows Update 页面问题处理

    Windows Update 服务器 服务器是联想RD640 操作系统Windows Server 2008 R2 Enterprise版 补丁版本是SP1 远程windows服务器时,一直处于远程建 ...

  7. 概率分布的python实现

    接上篇概率分布,这篇文章讲概率分布在python的实现. 文中的公式使用LaTex语法,即在\begin{equation}至\end{equation}的内容可以在https://www.codec ...

  8. MySQL5.6.36 自动化安装脚本

    背景 很好的朋友邱启明同学,擅长MySQL,目前任职某大型互联网业MySQL DBA,要来一套MySQL自动安装的Shell脚本,贴出来保存一些. 此版本为 MySQL 5.6.365 ###### ...

  9. 网络OSI七层模型以及数据传输过程

    网络OSI七层模型 模型图 国际标准化组织(ISO)制定了osi七层模型,iso规定了各种各样的协议,并且分了7层 每一层的详细信息 具体7层 数据格式 功能与连接方式 典型设备 应用层 Applic ...

  10. 负载均衡集群介绍、LVS介绍、LVS调度算法、LVS NAT模式搭建

    7月4日任务 18.6 负载均衡集群介绍18.7 LVS介绍18.8 LVS调度算法18.9/18.10 LVS NAT模式搭建 扩展lvs 三种模式详解 http://www.it165.net/a ...