Day 62 django form modelform组件
文章目录
1、批量操作数据
浏览器访问一个django路由 立刻创建10万条数据并展示到前端页面
create()、all()
涉及到大批量数据的创建 直接使用create可能会造成数据库崩溃
批量数据创建>>>:bulk_create()
批量数据修改>>>:bulk_update()
def index(request):;
for i inrange(100000):
models.Book.objects.create(title=f'第{i}本书')
book_list = []
for i inrange(100000):
book_obj = models.Book(title=f'第{i}本书')
book_list.append(book_obj)
models.Book.objects.bulk_create(book_list) # 批量创建数据
book_query = models.Book.objects.all()
return render(request,'booklist.html',locals())
当数据比较大的时候 数据应该考虑分页
通过divmod()
获取总数居和分页展示的数据得出的总页码
前端模板语法不支持rang 但是后端支持 我们可以在后端创建好html标签 然后传递给html页面使用
2、自定义分页器
def booklist(request):
from app01.plugins import mypage
book_query = models.Book.objects.all()
page_obj = mypage.Pagination(current_page=request.GET.get('page'),
all_count=book_query.count())
page_query = book_query[page_obj.start:page_obj.end]
return render(request,'book.html',locals())
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
{% for book_obj in page_query %}
<p class="text-center">{{book_obj.title }}</p>
{% endfor %}
<p>{{ page_obj.page_html|safe }}</p>
</div>
</div>
</div>
3、form组件
前戏:编写用户登录功能并且校验数据返回提示信息(form表单)
def reg(request):
data_dict={'name':'','pwd':''}
if request.method=='POST':
name=request.POST.get('name')
pwd = request.POST.get('pwd')
if name =='kk':
data_dict['name']='kk已存在'
if pwd =='123':
data_dict['pwd']='密码太简单了'
return render(request,'reg.html',locals())
form组件
- 数据校验
支持提前设置各种校验规则 之后自动校验 - 渲染页面
支持直接渲染获取用户数据的各种标签 - 展示信息
支持针对不同的校验失败展示不同的提示
form类型创建
from django import forms
class Myreg(forms.Form):
name = forms.CharField(max_length=8,min_length=3)
pwd = forms.CharField(min_length=3)
age = forms.CharField(max_length=150,min_length=0)
email = forms.EmailField() #邮箱必须符合邮箱格式(至少有@符号)
3.1、数据校验功能
-
传递待校验的数据
form_obj = views.Myreg({'name':'kk','pwd':'123','age':21,'email':5555})
-
判断所有数据 是否符合校验
form_obj.is_valid()
-
获取符合校验规则的数据
form_obj.cleaned_data {'pwd': '123', 'age': '21'}
-
查阅不符合校验规则的数据及错误原因
form_obj.errors {'name': ['Ensure this value has at least 3 characters (it has 2).'], 'email': ['Enter a valid email address.']}
form类中编写的字段默认都是必填的 少传则肯定通不过校验 is_valid
校验如果多传了一些字段 则不参与校验 全程忽略
3.2、渲染标签功能
django 模板语法注释
<# 注释 #>
方式一:(封装成都高 扩展性差)
{{ form_obj.as_p }} # 渲染成三个 p标签下
{{ form_obj.as_table }} # 直接渲染成leable
{{ form_obj.as_ul }} # 以无序列表形式
方式二:(封装成都低 扩展性好 编写困难)
{{ form_obj.name.lable }} # 只拿字段名
{{ form_obj.name }} # 输入框
{{ form_obj.age.lable }}
{{ form_obj.age }}
{{ form_obj.email.lable }}
{{ form_obj.email }}
可以通过改 类中 字段 添加 lable关键字参数值 来修改 字段名
方式三(推荐使用)
# 也可以通过 类中lable添加参数修改字段名
{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}</p>
{% endfor %}
3.3、展示提示信息
form组件 自带校验规则
创建form类 通过函数将form类 传至前端 前端自动会校验
form表单如何取消浏览器自动添加的数据校验功能
novalidate
#前端
<form action="/app01/func/" method="post" novalidate> # 在form中填写 novalidate
{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}</p>
{% endfor %}
<input type="submit" name="提交">
#后端
def func(request):
form_obj=Myreg()
if request.method=='POST':
form_obj=Myreg(request.POST)
if form_obj.is_valid():
print(form_obj.cleaned_data)
else:print(form_obj.errors)
return render(request,'form_reg.html',locals())
错误提示底层原理
def func(request):
form_obj=Myreg()
if request.method=='POST':
form_obj=Myreg(request.POST)
if form_obj.is_valid():
print(form_obj.cleaned_data)
else:print(form_obj.errors) # form_obj.errors 获取到错误信息 传给后端
return render(request,'form_reg.html',locals())
<form action="/app01/func/" method="post" novalidate>
{# {{ form_obj.as_p }}#}
{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}
<spen style="color: red;">{{ foo.errors.0 }}</spen> #这里 将 form的每一条对应的错误 取其 错误 文本信息展示
</p>
{% endfor %}
<input type="submit" name="提交">
数据校验正确的话 直接将正确的数据字典 直接传至数据库
def func(request):
form_obj=Myreg()
if request.method=='POST':
form_obj=Myreg(request.POST)
if form_obj.is_valid():
data_dict=form_obj.cleaned_data
models.User.objects.create(**data_dict) # 直接传至数据库
else:print(form_obj.errors)
return render(request,'form_reg.html',locals())
3.4、重要字段参数
参数 | 功能 |
---|---|
max_length/min_length | 字符最大长度值和最小值 |
max_value/min_value | 数字 最大长度值 和最小值 |
label | 字段注释(修改字段名) |
error_messages | 错误提示 |
required | 是否为空 |
widget | 标签类型、标签属性 |
inital | 默认值 |
validators | 正则校验(需要倒模块) |
4、钩子函数
提供自定义的校验方式
4.1、局部钩子
校验单个字段
class Myreg(forms.Form):
name = forms.CharField(max_length=8,min_length=3,label='用户名')
pwd = forms.CharField(min_length=3,label='密码')
pwd_again=forms.CharField(min_length=3,label='确认密码')
age = forms.IntegerField(max_value=150,min_value=0,label='年龄')
email = forms.EmailField() #邮箱必须符合邮箱格式(至少有@符号)
#校验用户名是否一致 局部钩子
def clean_name(self):
name = self.cleaned_data.get('name')
res = models.User.objects.filter(name=name).first()
if res:
return self.add_error('name','用户名已存在')
return name
4.2、全局钩子
校验两次密码是否一致
class Myreg(forms.Form):
name = forms.CharField(max_length=8,min_length=3,label='用户名')
pwd = forms.CharField(min_length=3,label='密码')
pwd_again=forms.CharField(min_length=3,label='确认密码')
age = forms.IntegerField(max_value=150,min_value=0,label='年龄')
email = forms.EmailField() #邮箱必须符合邮箱格式(至少有@符号)
#2 校验两次密码是否一致
def clean(self):
pwd =self.cleaned_data.get('name')
pwd_again=self.cleaned_data.get('pwd_again')
if not pwd==pwd_again:
return self.add_error('pwd_again','两次密码不一致')
return self.cleaned_data
5、modelform组件
modelform是form的优化版本 使用更简单 功能更强大
class MymodelForm(forms.ModelForm):
class Meta:
model = models.User
fields = '__all__'
labels={ #填写字段被指
'name': '用户名',
}
def func1(request):
md_obj=MymodelForm()
if request.method == 'POST':
#如果要修改字段的话 需要将修改的字段 查找出来 然后传给 modelform 对象
# edit_obj = models.User.objects.filter(name='ming').first()
md_obj = MymodelForm(request.POST) #修改字段的参数 instance=edit_obj
if md_obj.is_valid():
md_obj.save()
return render(request,'md_reg.html',locals())