多对多三种创建方式

	forms校验性组件

	django settings源码

昨日内容

ajax结合sweetalert
自己写一个删除按钮的确认框 去github上下载sweetalert源码 你只需要使用里面dist文件夹
gitlab
公司自己搭建
码云 参考示例书写即可 二次开发能力
基于人家已经写好的功能修改
1.先看别人的配置参数
2.前期就是猜
3.整体修改
linux
redis
mongodb
github
git 批量处理
bulk_create()
当你要批量操作数据库的时候 一定要减少走数据库的频率 数据的分页展示
django其实有内置的分页模块
但是该模块不好用,书写麻烦,功能不健全 自定义分页
1.queryset支持切片操作
2.研究当前页 每页展示多少条数据 起始位置 终止位置
3.前端代码不一定非要在前端书写 后端也可以 把自定义的代码拷贝到本地
基本使用
将代码放入到一个py文件中 导入该文件中的类 1.生成该类的对象
展示数据的总条数
用户想访问的页码
默认参数每页展示几条数据
分页页码的个数 奇数位 2.前端使用
qeuryset部分
|safe

多对多三种创建方式

封装程度越高,可扩展性越差

1.全自动

一般情况下

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

好处

  • 自始至终你都没有操作第三张表,全部都是有orm自动帮你创建
  • 内置了四个操作第三张表的方法
    • add

      remove

      set

      clear

缺点

  • 自动创建的第三张表无法扩展和修改字段,表的扩展性较差

2.纯手动

了解

class Book(models.Model):
title = models.CharField(max_length=32) class Authors(models.Model):
name = models.CharField(max_length=32) # 自建第三张表 class Book2Authors(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Authors') # 可以手动创建第三张表中的字段
create_time = models.DateField(auto_now_add=True)

好处

  • 第三张表中字段个数和字段名称全都可以自己定义

缺点

  • 不再支持orm跨表查询,没有正反向的概念
  • 不能使用修改字段方法
    • add

      remove

      set

      clear

3.半自动through='',through_fields=(外键字段)

推荐使用

# 半自动
class Book(models.Model):
title = models.CharField(max_length=32) # 多对多关系字段
authors = models.ManyToManyField(to='Authors',through='Book2Authors',through_fields=('authors','book')) class Authors(models.Model):
name = models.CharField(max_length=32) # 自建第三张表
class Book2Authors(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Authors')
# 该表中有任意多的外键字段
  • through='第三张表名'指定了不自动创建,手动创建的第三张表名,并与之关联
  • through_fields=('','')指定了第三张表中的到底哪两个字段维护表之间多对多关系,外键在哪,哪个字段在前面
当你的ManyToMany只有一个参数to的情况下orm会自动帮你创建第三张表
如果你加了throug和through_fields那么orm就不会自动帮你创建第三张表,但是他会在内部帮你维护关系,让你能够继续使用orm的跨表查询 through 自己制定第三张表关系
through_fields 自己制定第三张表中到底哪两个字段维护这表与表之间的多对多关系,外键在哪个表中,参数放在前面

好处

  • 可以任意的添加和修改第三张表中的字段
  • 支持orm跨表查询

缺点

  • 不支持表字段的修改方法
  • add

    remove

    clear

    set

forms组件

1.简单引入

需求:
注册页面,获取用户输入的用户名和密码
提交到后端之后,后端需要对用户名和密码进行校验
用户名中不能含有'金 瓶 梅'
密码不能少于三位
如果不符合,展示响应的错误信息

views

from django.shortcuts import render,HttpResponse,redirect

# Create your views here.

def register(request):
# get请求来的时候直接走的是空值字典
errors = {'username':'','password':''}
# 当请求方式是post时给字典赋值
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if '金 瓶 梅' in username:
errors['username'] = '不符合社会主义核心价值观' if len(password) < 4:
errors['password'] = '注意注意太少了'
return render(request,'register.html',locals())

register.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>简易校验用户的输入功能</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="bootstrap-3.3.7-dist/js/bootstrap.min.js"></script> </head>
<body> <form action="" method="post">
<p>username
<input type="text" name="username">
<span style="color: red">{{ errors.username }}</span>
</p>
<p>password
<input type="text" name="password">
<span style="color: red">{{ errors.password }}</span>
</p>
<input type="submit">
</form>
</body>
</html>

以上代码简单做到的事

  • 手动书写html代码获取用户输入 -- 渲染标签
  • 将数据传递给后端做数据校验 -- 校验数据
  • 如果有数据错误,你还展示了错误信息 -- 展示信息

2.forms组件作用

能够做的事情就是上面的三步

  • 渲染标签
  • 校验数据
  • 展示信息

使用forms组件的第一步,必须先写一个类

from django import  forms

from django import  forms

class MyForm(forms.Form):
# username字段 最少三位,最多八位
username = forms.CharField(max_length=8,min_length=3)
# password字段 最少三位,最多八位
password = forms.CharField(max_length=8,min_length=3)
# email字段 必须是邮箱格式
email = forms.EmailField()

测试用pycharm

右下角 python console
自动创建测试环境

2.1 校验数据

实例化创建的类,传入字典,字典中是需要校验的数据,获得对象form_obj

form_obj = views.MyForm({'username':'jason','password':'12','email':'123'})

1.is_vaild 查看是否合法

form_obj.is_valid()

False  # 只有当你的数据全部符合校验规则的情况下 结果才是True 否则都为False

2..errors 查看不符合的字段及原因

form_obj.errors

{
'password': ['Ensure this value has at least 3 characters (it has 2).'],
'email': ['Enter a valid email address.']
}

3.cleaned_data 查看符合的数据

form_obj.cleaned_data

{'username': 'jason'}

4.传值的顺序(少传值与多传值)

forms组件中 定义的字段默认都是必须传值的 不能少传

少传了字段会报错
form_obj = views.MyForm({'username':'jason','password':'12345'}) form_obj.is_valid()
False form_obj.errors
{'email': ['This field is required.']}

forms组件只会校验forms类中定义的字段 如果你多传了 不会有任何影响

多设置字段并不会影响
form_obj = views.MyForm({'username':'jason','password':'12345','email':'123@qq.com','xxx':'嘿嘿嘿'}) form_obj.is_valid()
True

2.2 渲染标签

第一步需要生成一个空的forms类的对象

class MyForm(forms.Form):
pass def index(request):
第一步需要生成一个空的forms类的对象
form_obj = MyForm()
直接将生成的对象传递给前端页面
return render(request,'index.html',locals())
  • froms组件只会帮你渲染获取用户输入的标签 不会帮你渲染提交按钮 需要你自己手动添加

第一种as_p as_ul as_table

直接将所有的信息一起渲染出来

reg.html

Copy<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<title>Title</title>
</head>
<body>
<div class="container">
<div class="row">
{#第一种渲染方式#}
<div class="col-md-offset-2 col-md-8">
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<hr>
{{ form.as_table }}
<hr>
{{ form.as_ul }}
<hr>
<input type="submit" value="提交" class="btn btn-success">
</form>
</div> </div>
</div>
</body>
</html>

这种方式, Django的封装程度太高了, 我们完全不能够自定义样式, 所以它只能用来前期的页面快速搭建以及做测试使用. 最后的渲染结果巨丑无比... 实际基本不考虑它.

第二种

单独渲染每一个标签

<p>forms组件渲染标签方式2(不推荐使用,写起来太多)</p>
{#input框的提示信息 获取input框#}
{{ form_obj.username.label }}{{ form_obj.username }}

当我们使用form对象.字段名字的时候, 可以发现这样只渲染出单独的一个input框. 检查还能发现form组件渲染完毕后的一些规律.

第三种

上面这种方式也有一个不好的地方, 就是当字段多了以后, 每一个都需要添加类似的样式, 就比较麻烦, 这时候就需要用到第三种方式

遍历form对象来渲染出标签. 只需要对form对象作出以下小的变化, 就可以达到同样的效果

{% for form in form_obj %}
<p>{{ form.label }}{{ form }}</p>
{% endfor %}

可以定义类的label默认设置来渲染出页面的标签

class RegForm(forms.Form):
# 接下来的定义需要与模型表的字段类型一一对应
username = forms.CharField(
max_length=15, # 用户名最大长度为15
min_length=3, # 用户名的最小长度为3
label='用户名', # 渲染出在页面上的标签的名字
)
password = forms.CharField(
max_length=15, # 密码最大长度为15
min_length=3, # 密码的最小长度为3
label='密码', # 渲染出在页面上的标签的名字
)

2.3 展示信息

告诉浏览器不做前端校验 form表单设置novalidate参数即可

<form action="" method="post" novalidate>

如何校验前端用户传入的数据

展示错误信息

views

def index(request):
# 获得空的forms类对象
form_obj = MyForm()
# 校验前端用户传入的数据
if request.method == 'POST':
# 获取用户的数据,在request.POST中,forms组件校验数据
form_obj = MyForm(request.POST) # 该变量名一定要与上面的变量名一致
if form_obj.is_valid():
print(form_obj.cleaned_data)
return HttpResponse('数据全部')
else:
print(form_obj.errors)
return render(request,'index.html',locals()) ------------------------------------------------------- index.html <form action="" method="post" novalidate>
{% for form in form_obj %}
<p>
{{ form.label }}{{ form }}
{# form 等价于方式2中的对象点字段名(使用.0获取列表中的信心)#}
<span>{{ form.errors.0 }}</span>
</p>
{% endfor %}
<input type="submit">
</form>

参数设置

class MyForm(forms.Form):
# username字段 最少三位,最多八位
username = forms.CharField(max_length=8,min_length=3,label='用户名',
error_messages={
'max_length':'用户名最长8位',
'min_length':'用户名最短3位',
'required':'用户名不能为空'
})
# email字段 必须是邮箱格式
email = forms.EmailField(label='邮箱',
error_messages={
'required':'邮箱不能为空',
'invalid':'邮箱格式错误'
})
  • label= 设置提示信息

  • error_messages={}设置报错信息

    • required 不能为空
    • invalid 邮箱格式
  • validations 内置校验器

    RegexValidator 正则校验

2.4 校验数据补充

内置的校验器

内置的校验器
from django.core.validators import RegexValidator
validators=[
RegexValidator(r'^[0-9]+$', '请输入数字'),
RegexValidator(r'^159[0-9]+$', '数字必须以159开头'),
]

钩子函数 HOOK

会在普通校验全部符合后开始校验

上面只靠类型检查明显不符合一些比较复杂的校验, 例如用户名不能包含敏感词, 两次密码需要一致, 这都需要进行校验.

类内部的方法,是一个函数,函数体内你可以写任意的校验

局部钩子 clean_字段值

单独校验某一个字段的

.add_error展示某一字段的错误信息

最后需返回字段数据return username

类中定义函数:
# 校验用户名中不能含有666 def clean_username(self):
# 校验通过的数据在 cleaned_data
username = self.cleaned_data.get('username')
# 第二层的判断
if '666' in username:
# 给username字段对应的框显示错误信息
self.add_error('username','后面的是报错')
# 将username数据返回
return username

全局钩子 clean

校验多个字段之间的关系的

return全局的数据return self.cleaned_data

类中
# 校验两次密码是否一致 def clean(self):
password = self.cleaned_data.get('password')
re_password = self.cleaned_data.get('re_password')
if not password == re_password:
self.add_error('re_password','两次密码不一致')
# 将全局的数据返回
return self.cleaned_data

补充知识点

小猿取经博客园密码
xiaoyuanqujing@666

其他字段及参数

其他字段属性

  • lable 设置input对应的提示信息

  • initial 给input框设置默认值

  • required 默认为True,控制字段是否为空

  • widget 设置密码文本的显示方式

    • widget=forms.widgets.PasswordInput()

      from django.forms import widgets
      
      widget=forms.widgets.PasswordInput()
    • widget=forms.widgets.TextInput()

      括号内可以设置类内的属性 填写字典{},添加多个参数空格连接
      
      widget=forms.widgets.TextInput({'class':'form-control c1 c2','username':'jack'})

initial

初始值,input框里面的初始值。

class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三" # 设置默认值
)
pwd = forms.CharField(min_length=6, label="密码")

error_messages

重写错误信息。

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="密码")

password

class LoginForm(forms.Form):
...
pwd = forms.CharField(
min_length=6,
label="密码",
widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
)

radioSelect

单radio值为字符串

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()
)

choice字段注意事项

在使用选择标签时,需要注意choices的选项可以配置从数据库中获取,但是由于是静态字段 获取的值无法实时更新,需要重写构造方法从而实现choice实时更新。

方式一:

from django.forms import Form
from django.forms import widgets
from django.forms import fields class MyForm(Form): user = fields.ChoiceField(
# choices=((1, '上海'), (2, '北京'),),
initial=2,
widget=widgets.Select
) def __init__(self, *args, **kwargs):
super(MyForm,self).__init__(*args, **kwargs)
# self.fields['user'].choices = ((1, '上海'), (2, '北京'),)
# 或
self.fields['user'].choices = models.Classes.objects.all().values_list('id','caption')

方式二:

from django import forms
from django.forms import fields
from django.forms import models as form_model class FInfo(forms.Form):
authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all()) # 多选
# authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all()) # 单选

1203 forms组件的更多相关文章

  1. Django学习之八:forms组件【对form舒心了】

    目录 Django forms组件 bound and unbound form instance forms渲染有关 隐藏一个字段,不渲染它 form 校验 form类 ModelForm 利用Mo ...

  2. Django组件-Forms组件

    Django的Forms组件主要有以下几大功能: 页面初始化,生成HTML标签 校验用户数据(显示错误信息) HTML Form提交保留上次提交数据 一.小试牛刀 1.定义Form类 from dja ...

  3. Django组件--forms组件(注册用)

    一.forms组件--校验类的使用 二.form组件--校验类的参数 三.forms组件校验的局部钩子--自定义校验规则(要看源码理解) 四.forms组件校验的全局钩子--校验form表单两次密码输 ...

  4. web框架开发-Django的Forms组件

    校验字段功能 针对一个实例:用户注册. 模型:models.py class UserInfo(models.Model): name=models.CharField(max_length=32) ...

  5. python django(forms组件)

    forms组件最大的作用,就是做数据校验. 普通做法,一个一个写校验规则,没有解耦.校验规则,都在视图函数里面. 网页校验 修改urls.py,增加路径addbook from app01 impor ...

  6. Auth模块、Forms组件

    Auth模块 auth模块是Django自带的用户认证模块: 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这 ...

  7. django之forms组件

    在django中forms组件有其强大的功能,里面集合和众多的函数和方法:下面来看一下它的源码 """ Form classes """ f ...

  8. forms组件

    昨日回顾: 批量插入数据: -queryset的方法:bulk_create(对象列表,数字(一次插入多少)) 分页器: from django.core.paginator import Pagin ...

  9. (32)forms组件(数据校验)

    forms组件的用处 1.就是用来做数据校验的 2.渲染页面 3.渲染错误信息(和局部刷新同效果) 数据校验 要使用forms组件必须要写一个类继承forms组件 urls.py from bbs01 ...

随机推荐

  1. eNSP上VLAN的基础的配置及access接口

    本实验模拟公司内部,为不同的部门划分不同的VLAN ,形成的不同广播域,来保护信息的安全,拓扑图如下所示

  2. ubuntu18.10 修改MySQL编码为utf-8

    首先登陆mysql的交互shell,输入下面的命令查看当前数据库的编码方式 show variables like '%character%'; 从上面可以看出,mysql数据库装上之后初始并不均是u ...

  3. Linux【Ubuntu】安装docker

    内核要大于3.10才能安装docker 查看内核 uname -r 安装yum命令 sudo apt install yum 由于 apt 源使用 HTTPS 以确保软件下载过程中不被篡改,故添加使用 ...

  4. [转帖]负载均衡 LVS+Keepalived

    负载均衡 LVS+Keepalived https://www.cnblogs.com/jicki/p/5546862.html 改天试试 一直没搞过. 系统  CentOS 5.6 X64 物理机 ...

  5. [转帖]一文尽懂 USB4

    一文尽懂 USB4 https://www.ithome.com/0/451/062.htm 今年 3 月份,USB Promoter Group(领导小组)首次发布了 USB4 规范,即下一代 US ...

  6. STL源码剖析——空间配置器Allocator#1 构造与析构

    以STL的运用角度而言,空间配置器是最不需要介绍的东西,因为它扮演的是幕后的角色,隐藏在一切容器的背后默默工作.但以STL的实现角度而言,最应该首先介绍的就是空间配置器,因为这是这是容器展开一切运作的 ...

  7. I2C基础及时序

    1.模式 标准模式:达到100Kb/S 快速模式:达到400Kb/S 2.连接图  3.协议 SDA.SCL在空闲的时候为高电平 重点!重点!重点!  4.涉及到多主机仲裁的竞争及时钟信号的同步

  8. Spring AOP日志实现(四)--Bean的设计

    日志Bean的设计: 类名及方法名:

  9. Go net/http 发送常见的 http 请求

    使用 golang 中的 net/http 包来发送和接收 http 请求 开启 web server 先实现一个简单的 http server,用来接收请求 package main import ...

  10. jQuery遍历(3)

    上期我们讲了遍历的祖先.后代和同胞的问题,现在我们讲讲遍历遍历过滤 三个最基本的过滤方法是:first(), last() 和 eq(),它们允许您基于其在一组元素中的位置来选择一个特定的元素.其他过 ...