多对多三种创建方式

全自动

  • 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的更多相关文章

  1. Django 09 博客小案例

    Django 09 博客小案例 urls.py from django.urls import path from . import views urlpatterns = [ path('index ...

  2. Windows7WithSP1/TeamFoundationServer2012update4/SQLServer2012

    [Info   @09:03:33.737] ====================================================================[Info   @ ...

  3. 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: [' ...

  4. Django框架09 /ajax、crsf、settings导入

    Django框架09 /ajax.crsf.settings导入 目录 Django框架09 /ajax.crsf.settings导入 1. ajax概述 2. ajax应用 3. ajax上传文件 ...

  5. Django 2.0 学习(09):Django 静态文件(样式和背景图片)

    应用的定制化:静态文件 首先,在polls目录中创建一个名叫static的目录.Django会在该目录里面查找静态文件,类似于Django在polls/template目录下查找模板文件. Djang ...

  6. 09 - Django应用第六步

    1 自定义页面 在项目中, 肯定不会只是显示单纯的HTML文件, 我们可能还需要JS, CSS, 图片等 这些文件就被称为静态文件(starIc files) 在小的项目中, 可能静态文件比较少, 但 ...

  7. 09 Django组件之用户认证组件

    没有学习Django认证组件之前使用装饰器方法 from django.shortcuts import render, HttpResponse, redirect from app01.MyFor ...

  8. Django-中间件-csrf扩展请求伪造拦截中间件-Django Auth模块使用-效仿 django 中间件配置实现功能插拔式效果-09

    目录 昨日补充:将自己写的 login_auth 装饰装在 CBV 上 django 中间件 django 请求生命周期 ***** 默认中间件及其大概方法组成 中间件的执行顺序 自定义中间件探究不同 ...

  9. 09.Django基础七之Ajax

    一 Ajax简介 1.简介 AJAX(Asynchronous Javascript And XML)翻译成中文就是"异步的Javascript和XML".即使用Javascrip ...

随机推荐

  1. PHP laravel+thrift+swoole打造微服务框架

    Laravel作为最受欢迎的php web框架一直广受广大互联网公司的喜爱. 笔者也参与过一些由laravel开发的项目.虽然laravel的性能广受诟病但是业界也有一些比较好的解决方案,比如堆机器, ...

  2. 一.web服务机制

    web服务机制 我们先跟着**(Web服务器工作原理总体描述01)这张图,将一次Web服务的工作流程过一遍,我们假设以浏览器作为客户端(1) 用户做出了一个操作,可以是填写网址敲回车,可以是点击链接, ...

  3. deepin MySQL 安装以及编码格式的修改utf-8

    deepin MySQL 安装以及编码格式的修改utf-8: 1.sudo apt-get install mysql-server mysql-client 2.sudo mysql -u root ...

  4. .NET Core 获取数据库上下文实例的方法和配置连接字符串

    目录 .NET Core 获取数据库上下文实例的方法和配置连接字符串 ASP.NET Core 注入 .NET Core 注入 无签名上下文 OnConfigure 配置 有签名上下文构造函数和自己n ...

  5. python高阶函数的使用

    目录 python高阶函数的使用 1.map 2.reduce 3.filter 4.sorted 5.小结 python高阶函数的使用 1.map Python内建了map()函数,map()函数接 ...

  6. AE安装部署以及监测ArcEngine runtime 9.3是否安装

    目的:用ArcEngine9.3开发项目以后,用Visual Studio2008打包工具打包: 同时监测别的机器上是否有ArcEngine Runtime或者Desktop的支持. 解决方案: 1. ...

  7. php为什么要用swoole?

    最近两个月一直在研究 Swoole,那么借助这篇文章,我希望能够把 Swoole 安利给更多人.虽然 Swoole 可能目前定位是一些高级 phper 的玩具,让中低级望而生畏,可能对一些应用场景也一 ...

  8. iOS开发tips-PhotoKit

    概述 PhotoKit应该是iOS 8 开始引入为了替代之前ALAssetsLibrary的相册资源访问的标准库,后者在iOS 9开始被弃用.当然相对于ALAssetsLibrary其扩展性更高,ap ...

  9. 【python测试开发栈】—python内存管理机制(二)—垃圾回收

    在上一篇文章中(python 内存管理机制-引用计数)中,我们介绍了python内存管理机制中的引用计数,python正是通过它来有效的管理内存.今天来介绍python的垃圾回收,其主要策略是引用计数 ...

  10. 网页解析之BeautifulSoup

    介绍及安装 Beautiful Soup 是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据. BeautifulSoup 用来解析 HTML 比较简单,API非常人 ...