多对多三种创建方式

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

全自动

  1. class Book(models.Model):
  2. title = models.CharField(max_length=255)
  3. # 多对多关系字段
  4. authors = models.ManyToManyField(to='Authors')
  5. class Authors(models.Model):
  6. name = models.CharField(max_length=32)

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

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

全手动

  1. class Book(models.Model):
  2. title = models.CharField(max_length=255)
  3. class Authors(models.Model):
  4. name = models.CharField(max_length=32)
  5. class Book2Author(models.Model):
  6. book = models.ForeignKey(to='Book')
  7. author = models.ForeignKey(to='Authors')
  8. # 添加其他字段
  9. create_time = models.DateField(auto_now_add=True)

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

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

半自动

  1. class Book(models.Model):
  2. title = models.CharField(max_length=255)
  3. # 添加多对多关系字段
  4. authors = models.ManyToMangField(to='Authors', through='Book2Author', through_fields=('book','authors'))
  5. # through 告诉orm 用我自己建的外键
  6. class Authors(models.Model):
  7. name = models.CharField(max_length=32)
  8. class Book2Author(models.Model):
  9. book = models.ForeignKey(to='Book')
  10. author = models.ForeignKey(to='Authors')
  11. # 添加其他字段
  12. create_time = models.DateField(auto_now_add=True)
  13. # 该表中可以有任意多的外键字段

​ 当你的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 是添加属性的

  1. # form组件模块导入
  2. from django import forms
  3. # 自定义form类 继承forms.Form
  4. class MyForm(forms.Form):
  5. # 定义需要校验和前端展示的标签或字段
  6. username = forms.CharField(max_length=8, min_length=3, label='用户名', required=True,
  7. initial='输入....',
  8. error_messages={
  9. 'max_length':'最大8位',
  10. 'min_length':'最小3位',
  11. 'required':'不能为空',
  12. },
  13. widget=forms.widgets.TextInput(attrs={'class':'you is sd'})
  14. )
  15. password = forms.CharField(max_length=16, min_length=5, label='密码', required=True,
  16. initial='输入密码.....',
  17. error_messages={
  18. 'max_length':'最大16位',
  19. 'min_length':'最小3位',
  20. 'required':'不能为空',
  21. },
  22. widget=forms.widgets.PasswordInput(attrs={'class':'password'})
  23. )
  24. email = forms.EmailField(label='邮箱',error_messages={
  25. 'required':'不能为空',
  26. 'invalid':'格式不正确'
  27. })

form_obj 及 is_valid()

  1. def form(request):
  2. # 生成MyForm对象
  3. form_obj = MyForm()
  4. # 判断是否是post请求
  5. if request.method == 'POST':
  6. form_obj = MyForm(request.POST)
  7. # 判断数据是否通过校验
  8. if form_obj.is_valid():
  9. print('校验成功')
  10. return HttpResponse('校验成功')
  11. else:
  12. return render(request, 'test.html', locals())
  13. return render(request, 'test.html', locals())

前端渲染方式

  1. {# 方式一 #}
  2. {{ form_obj.as_p }}
  3. {{ form_obj.as_ul }}
  4. {{ form_obj.as_table }}
  5. {# 方式二 #}
  6. <p>{{ form_obj.username.label }}:{{ form_obj.username }}</p>
  7. <p>{{ form_obj.password.label }}:{{ form_obj.password }}</p>
  8. <p>{{ form_obj.email.label }}:{{ form_obj.email }}</p>
  9. {# 方式三 #} {# 推荐使用 #}
  10. {# 使用对象点errors.0 拿到校验错误信息#}
  11. {% for foo in form_obj %}
  12. <p>{{ foo.label }}:{{ foo }}<span>{{ foo.errors.0 }}</span></p>
  13. {% endfor %}

取消前端自动校验

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

正则校验

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

钩子函数(Hook方法)

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

cleaned_data

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

主动抛错误信息

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

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

局部钩子

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

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

全局钩子

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

  1. # 局部钩子固定写法 clean
  2. def clean(self):
  3. password = self.cleaned_data.get('password')
  4. confirm_password = self.cleaned_data.get('confirm_password')
  5. if not password == confirm_password:
  6. self.add_error('confirm_password', '两次密码不一致')
  7. return self.cleaned_data

多选框(了解知识点)

radioSelect

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

单选Select

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

多选Select

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

单选checkbox

  1. class LoginForm(forms.Form):
  2. ...
  3. keep = forms.ChoiceField(
  4. label="是否记住密码",
  5. initial="checked",
  6. widget=forms.widgets.CheckboxInput()
  7. )

多选checkbox

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

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. MySQL数据库的主从同步

    什么要进行数据库的主从同步? 防止单点故障造成的数据丢失 主从复制的原理 MySQL从数据库开启I/O线程,向主服务器发送请求数据同步(获取二进制日志) MySQL数据库开启I/O线程回应从数据库 从 ...

  2. libwebsocket协议切换状态机

    libwebsocket为连接(connection)定义了一组状态机-lws_connection_states,通过状态机我们来看libwebsocket如何实现协议的切换.除了lws_conne ...

  3. PostGIS 结合Openlayers以及Geoserver实现最短路径分析(一)

    环境: Win10 ArcMap10.4(用于数据处理) postgresql9.4 postgis2.2.3 pgRouting2.3(postgresql插件) ##附上本文配套素材下载地址:ht ...

  4. 学习PHP框架只停留在会用层面,职业生涯肯定走不远!

    工作这么多年,也面试过很多PHP工程师,我发现很多PHP工程师只停留在使用框架的层面,然而对框架底层根本没有深入去了解,那么这就会给自己的职业生涯带来一定的瓶颈,当遇到问题的时候你就无从下手,不知道如 ...

  5. 2019-11-3:渗透测试,基础学习,bypass类型笔记

    等价字符 空格:%20,+,(),%0a,%09,%a0,%0b,%0c,%0d,/**/等 =:like,regexp,liker,<>,! =等 and:&& or:x ...

  6. 几行代码轻松搞定python的sqlite3的存取

    很简单: 存数据: 1.加载sqlite3驱动(只需一行代码) 2.用驱动执行查询语句(只需一行代码) 取数据: 1.加载sqlite3驱动(只需一行代码) 2.用驱动执行查询语句(只需一行代码) 乍 ...

  7. day02_Requests模块

    1.anaconda的安装 1.1 .安装可执行程序 1.2 .配置环境变量 ​ 根据环境变量的先后顺序去查找可执行程序文件,如果查找到就执行,如果查找不到就报错. ​ anaconda主要配置: ​ ...

  8. pymongo的基本操作和使用

    MongoDB简介 MongoDB是一个开源的文档类型数据库,它具有高性能,高可用,可自动收缩的特性.MongoDB能够避免传统的ORM映射从而有助于开发. 文档 在MongoDB中,一行纪录就是一个 ...

  9. 在Asp.Net Core MVC 开发过程中遇到的问题

    1. Q: Razor视图中怎么添加全局模型验证消息 #### A:使用ModelOnly <div asp-validation-summary="ModelOnly" c ...

  10. #华为云·寻找黑马程序员#【代码重构之路】如何“消除”if/else

    1. 背景 if/else是高级编程语言中最基础的功能,虽然 if/else 是必须的,但滥用 if/else,特别是各种大量的if/else嵌套,会对代码的可读性.可维护性造成很大伤害,对于阅读代码 ...