多对多三种创建方式

# 补充知识点 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. centos 更换用户密码

    腾讯云报告了我的服务器被暴力破解了.... 因此需要更换更复杂的password, 命令为:passwd  用户名,例如下我要更换root的password [root@VM_0_4_centos ~ ...

  2. Install aws cli

    下载 https://s3.amazonaws.com/aws-cli/AWSCLI64PY3.msi 添加环境变量

  3. AppBoxFuture: 集成第三方Sql数据库

      框架设计之初是不准备支持第三方数据库的,但最近几个朋友都提到需要将旧的基于传统Sql数据库的应用迁移到框架内,主要是考虑到一方面目前框架内置的分布式数据库尚未完善,另一方面是希望能逐步迭代旧应用替 ...

  4. 【NHOI2018】黑格覆盖

    [题目描述] 在一张由 M * N 个小正方形格子组成的矩形纸张上,有 k 个格子被涂成了黑色.给你一张由 m * n 个同样小正方形组成的矩形卡片,请问该卡片最多能一次性覆盖多少个黑格子? [输入数 ...

  5. 浅析scrapy与scrapy-redis的区别

    首先,要了解两者的区别,就要清楚scrapy-redis是如何产生的,有需求才会有发展,社会在日新月异的飞速发展,大量相似网页框架的飞速产生,人们已经不满足于当前爬取网页的速度,因此有了分布式爬虫,让 ...

  6. Spring Boot 最流行的 16 条实践解读!【华为云技术分享】

    置顶:华为云618大促火热进行中,全场1折起,免费抽主机,消费满额送P30 Pro,点此抢购. Spring Boot是最流行的用于开发微服务的Java框架.在本文中,将与大家分享自2016年以来笔者 ...

  7. 用C在GBA上写光线追踪(0)配置开发编译环境

    前段时间用C#写了一个光线追踪程序,可以渲染圆球,平面这种基本图形,反射,光照,阴影,都大致尝试做了一下. ↑ C#实现的光线追踪     ↑ GBA上C实现的光线追踪 然而,在我打算继续深入优化的时 ...

  8. shell du sh 文件大小输出

    按照文件大小升序输出结果: du -sh * | sort -h 如果要逆序输出,则: du -sh * | sort -hr

  9. SpringMvc commons-fileupload图片/文件上传

    简介 SpringMvc文件上传的实现,是由commons-fileupload这个jar包实现的. 需求 在修改商品页面,添加上传商品图片功能. Maven依赖包 pom.xml <!-- 文 ...

  10. MySQL的存储(一、连接数据库)

    准备工作: 确保安装MySql 安装PyMySQL库 连接数据库: 这里首先尝试连接下数据库,假设当前MySQL运行在本地,用户名为root,密码为123456,运行端口为3306. 通过PyMySQ ...