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 }}
{{ form_obj.as_table }}
{{ 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关键字参数值 来修改 字段名
方式三(推荐使用)
{% 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>
{% 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)
return render(request,'form_reg.html',locals())
<form action="/app01/func/" method="post" novalidate>
{
{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}
<spen style="color: red;">{{ foo.errors.0 }}</spen>
</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()
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':
md_obj = MymodelForm(request.POST)
if md_obj.is_valid():
md_obj.save()
return render(request,'md_reg.html',locals())
|