Django 09
多对多三种创建方式
全自动
ManyToManyField(to=)- 优点: 无须自己创建多对多关系表, 支持orm跨表查询, 支持add, set, remove, clear方法
- 不足: 表的扩展性较差
class Book(models.Model):
name = models.CharField(max_length=255)
# 自动创建多对多关系表
authors = models.ManyToManyField(to='Author')
class Author(models.Model):
name = models.CharField(max_length=255)
纯手撸
- 优点: 字段完全由自己定义
- 不足: 不支持orm跨表查询, 不支持add, set, remove, clear方法
class Book(models.Model):
name = models.CharField(max_length=255)
class Author(models.Model):
name = models.CharField(max_length=255)
# 手动创建多对多关系表
class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Author')
create_time = models.DateTimeField(auto_now=True)
半自动(推荐)
半自动其实是在手动创建和自动创建的基础上, 利用
ManyToManyField()字段, 内部维护关系through='Book2Author'该参数表示通过张表来建立表关系through_fields=('book', 'authors')该参数表示通过括号内的两个字段维护关系, 以便支持orm跨表查询
优点: 可以任意添加和修改关系表中的字段, 支持orm跨表查询
不足: 不支持add, set, remove, clear方法
注意: 在哪一张表中创建多对多外键字段, 则through_fields传入的第一个参数就是该张表关联的字段
class Book(models.Model):
name = models.CharField(max_length=255)
# 半自动创建多对多关系表
authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book', 'authors'))
class Author(models.Model):
name = models.CharField(max_length=255)
class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Author')
create_time = models.DateTimeField(auto_now=True)
form组件
校验数据
- 导入:
from django import forms - 自定义一个类 , 添加字段, 设置字段的限制条件
form_obj=MyForm(data)传入一个待校验的字典数据, 实例化对象form_obj.is_valid()校验传入的数据是否符合字段的限制条件form_obj.errors返回一个字典, 存放不符合条件的字段以及错误信息forms.cleaned_data返回一个字典, 存放符合条件的字段和对应的数据- 默认所有的字段都必须传值, 不能少传, 多传的会被忽略
from django import forms
class MyForm(forms.Form):
# 用户名的长度不能超过10字符, 不能少于3个字符
username = forms.CharField(max_length=10, min_length=3)
# 密码位数不能小于六位
password = forms.CharField(min_length=6)
# 邮箱需要符合有邮箱格式
email = forms.EmailField()
# 在测试文件运行下面的代码
# 需要校验的数据
data = {'username': 'bigb', 'password': '12345', 'email': '123.com'}
# 1.传入需要校验的数据, 实例化对象
form_obj = views.MyForm(data)
# 2.is_valid() 判断数据是否符合条件
print(form_obj.is_valid())
# 3.errors 查看错误信息
print(form_obj.errors)
'''
{'password': ['Ensure this value has at least 6 characters (it has 5).'],
'email': ['Enter a valid email address.']}
'''
# 4.cleaned_data 查看符合条件的数据
print(form_obj.cleaned_data) # {'username': 'bigb'}
# 5.少传数据
data = {'username': 'bigb', 'password': '123456'}
form_obj = views.MyForm(data)
form_obj.is_valid()
Out[11]: False
form_obj.errors
Out[12]:
{'email': ['This field is required.']}
渲染标签
- forms组件只会渲染输入标签, 不会渲染提交标签
{{ form_obj.as_p }}{{form_obj.username.label}}拿到username字段的字段名(文本){{form_obj.username}}拿到username对应的input框{% for form in form_obj %} --- {{form.label}} {{form}}- 给字段添加label参数, 可以自定义label的值, 默认是等于字段名
class MyForm(forms.Form):
# 用户名的长度不能超过10字符, 不能少于3个字符
username = forms.CharField(max_length=10, min_length=3, label='用户名')
# 密码位数不能小于六位
password = forms.CharField(min_length=6)
# 邮箱需要符合有邮箱格式
email = forms.EmailField()
def index(request):
# 1.先生成一个空的form_obj
form_obj = MyForm()
# 2. 将form_obj发送到html文件
return render(request, 'index.html', locals())
<body>
<h1>forms组件渲染标签</h1>
{{ form_obj.as_p }}
{{ form_obj.as_table}}
{{ form_obj.as_ul}}
<input type="submit">
</body>
<body>
<h1>forms组件渲染标签</h1>
<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>
<input type="submit">
</body>
<!--推荐使用-->
<body>
<h1>forms组件渲染标签</h1>
{% for form in form_obj %}
<p>{{ form.label }}{{ form }}</p>
{% endfor %}
<input type="submit">
</body>
展示错误信息
在form表单标签中加入属性 :
novalidation来取消前端校验{{form.errors}}可以拿到校验后的错误信息, 是一个列表, 在前端渲染成ul标签, 因此:{{form.errors.0}}字段的
error_massages={}参数用来自定义报错信息- required: 不能为空
- max_length: 最大长度
- min_length: 最小长度
- invalid: 格式错误
class MyForm(forms.Form):
# 用户名的长度不能超过10字符, 不能少于3个字符
username = forms.CharField(max_length=10, min_length=3, label='用户名',
error_messages={
'required': '用户名不能为空',
'max_length': '长度不能超过10个字符',
'min_length': '长度不能小于3个字符'
})
# 密码位数不能小于六位
password = forms.CharField(min_length=6, label='密码',
error_messages={
'required': '密码不能为空',
'min_length': '密码长度不能少于6位'
})
# 邮箱需要符合有邮箱格式
email = forms.EmailField(label='邮箱', error_messages={
'required': '邮箱不能为空',
'invalid': '邮箱格式错误'
})
def index(request):
# 1.先生成一个空的form_obj
form_obj = MyForm()
# 2. 将form_obj发送到html文件
if request.method == 'POST':
form_obj = MyForm(request.POST)
return render(request, 'index.html', locals())
<form action="" method="post" novalidate>
{% for form in form_obj %}
<p>
{{ form.label }}{{ form }}
<span>{{ form.errors.0 }}</span>
</p>
{% endfor %}
<input type="submit">
</form>
validators校验器
Regexvalidator:通过正则表达式完成数据的校验validators=[RegexValidator('正则表达式', '错误提示信息')]
phone = forms.CharField(label='手机号码', validators=[
RegexValidator(r'^(1[3-9])\d{9}$', '请输入正确的手机号码!')])
钩子函数
- 钩子函数是对数据的最后一道校验
- 在我们自定义的类下面创建
self.add_error('字段名', '错误信息')给某个字段添加错误信息- 局部钩子函数返回校验字段
- 全局钩子函数返回
self.cleaned_data
# 局部钩子函数, 校验用户名中不能包含特殊字符
def clean_username(self):
username = self.cleaned_data.get('username')
forbidden_char = r'\'/!@#$%^&*()_+|}{":>?<'
for i in forbidden_char:
if i in username:
self.add_error('username', '用户名中不能包含特殊符号!')
return username # 函数名用到什么字段, 就返回什么字段
# 全局钩子函数, 校验密码和确认密码是否一致
def clean(self):
confirm_password = self.cleaned_data.get('confirm_password')
password = self.cleaned_data.get('password')
if confirm_password != password:
self.add_error('confirm_password', '密码输入不一致!')
return self.cleaned_data # 函数名(全局)用到什么字段, 就返回什么字段
补充
initial参数设置默认值required=Flase设置该字段可为空label参数设置input框对应的提示信息widget参数可以设置input标签的type参数和属性
widget=forms.widgets.PasswordInput()widget=forms.widgetds.TextInput({'class': 'form-control c1 c2', 'username':'bigb})
Django 09的更多相关文章
- Django 09 博客小案例
Django 09 博客小案例 urls.py from django.urls import path from . import views urlpatterns = [ path('index ...
- Windows7WithSP1/TeamFoundationServer2012update4/SQLServer2012
[Info @09:03:33.737] ====================================================================[Info @ ...
- django 报错Reverse for 'detail' with keyword arguments '{'pk': '2'}' not found. 1 pattern(s) tried: ['$post/(?P<pk>[0-9]+)/$']
Django报错:Reverse for 'detail' with keyword arguments '{'pk': '2'}' not found. 1 pattern(s) tried: [' ...
- Django框架09 /ajax、crsf、settings导入
Django框架09 /ajax.crsf.settings导入 目录 Django框架09 /ajax.crsf.settings导入 1. ajax概述 2. ajax应用 3. ajax上传文件 ...
- Django 2.0 学习(09):Django 静态文件(样式和背景图片)
应用的定制化:静态文件 首先,在polls目录中创建一个名叫static的目录.Django会在该目录里面查找静态文件,类似于Django在polls/template目录下查找模板文件. Djang ...
- 09 - Django应用第六步
1 自定义页面 在项目中, 肯定不会只是显示单纯的HTML文件, 我们可能还需要JS, CSS, 图片等 这些文件就被称为静态文件(starIc files) 在小的项目中, 可能静态文件比较少, 但 ...
- 09 Django组件之用户认证组件
没有学习Django认证组件之前使用装饰器方法 from django.shortcuts import render, HttpResponse, redirect from app01.MyFor ...
- Django-中间件-csrf扩展请求伪造拦截中间件-Django Auth模块使用-效仿 django 中间件配置实现功能插拔式效果-09
目录 昨日补充:将自己写的 login_auth 装饰装在 CBV 上 django 中间件 django 请求生命周期 ***** 默认中间件及其大概方法组成 中间件的执行顺序 自定义中间件探究不同 ...
- 09.Django基础七之Ajax
一 Ajax简介 1.简介 AJAX(Asynchronous Javascript And XML)翻译成中文就是"异步的Javascript和XML".即使用Javascrip ...
随机推荐
- 微擎框架商业版 V2.1.2 去后门一键安装版+去除云平台+无附带模块
下载地址:http://dd.ma/AdVvoDu5 关注微信公众号codervip,点击公众号菜单,获取提取码! 这个是一键安装版本,所以微擎安装比较简单,不用大家手动去改数据库了,而且修复上个2. ...
- nyoj 70-阶乘因式分解(二)(数学)
70-阶乘因式分解(二) 内存限制:64MB 时间限制:3000ms 特判: No 通过数:7 提交数:7 难度:3 题目描述: 给定两个数n,m,其中m是一个素数. 将n(0<=n<=2 ...
- nyoj 276-比较字母大小 (顺序比较, 逆序输出)
276-比较字母大小 内存限制:64MB 时间限制:3000ms 特判: No 通过数:13 提交数:15 难度:1 题目描述: 任意给出两个英文字母,比较它们的大小,规定26个英文字母A,B,C.. ...
- mysql基础之约束
约束的目的: 1.约束保证数据的完整性和一致性. 2.约束分为表级约束 和 列级 约束.(针对约束字段的数目的多少来确定的) 3.约束类型包括 not null (非空约束) primary key( ...
- Win32 COM组件 x Android Service
有些书在介绍和讲解android的Service组件时,会使用后台服务一词,并且与运行在主线程的Activity相对.因为后台一词很容易误解,服务一直运行在后台?什么线程在运行?服务一直有条线程在运行 ...
- 解放双手,在PC端进行Android真机调试
scrcpy简介(拼写是scrcpy,非Python爬虫框架Scrapy) 简单地来说,scrcpy就是通过adb调试的方式来将手机屏幕投到电脑上,并可以通过电脑控制您的Android设备.它可以通过 ...
- java多线程,多线程加锁以及Condition类的使用
看了网上非常多的运行代码,很多都是重复的再说一件事,可能对于java老鸟来说,理解java的多线程是非常容易的事情,但是对于我这样的菜鸟来说,这个实在有点难,可能是我太菜了,网上重复的陈述对于我理解这 ...
- Feature Fusion for Online Mutual Knowledge Distillation (CVPR 2019)
一.解决问题 如何将特征融合与知识蒸馏结合起来,提高模型性能 二.创新点 支持多子网络分支的在线互学习 子网络可以是相同结构也可以是不同结构 应用特征拼接.depthwise+pointwise,将特 ...
- 菜鸟系列Fabric源码学习 — 区块同步
Fabric 1.4 源码分析 区块同步 本文主要从源码层面介绍fabric peer同步区块过程,peer同步区块主要有2个过程: 1)peer组织的leader与orderer同步区块 2)pee ...
- 【NHOI2018】扑克游戏
[问题描述] 有一种别样“小猫钓鱼”扑克游戏.有 N 张牌,每张牌都有一个花色和点数.游戏的规则:扑克接龙时,若前面有同样花色的牌,你可以将这两张牌连同之间的牌都取走,得到的分值为取走牌点数之和.这里 ...