Django组件:分页器

目录结构:

urls.py

from django.contrib import admin
from django.urls import path from app01 import views urlpatterns = [
path('admin/', admin.site.urls),
path(r"index/",views.index)
]

models.py

from django.db import models

# Create your models here.

class Book(models.Model):

    title = models.CharField(max_length=32)
price = models.DecimalField(decimal_places=2,max_digits=8)

views.py

from django.shortcuts import render

# Create your views here.

from app01.models import Book

# 导入分页器
from django.core.paginator import Paginator,EmptyPage def index(request): """
# 批量插入数据
# for i in range(100):
# Book.objects.create(title="book_%s"%i,price=i*i)
# 但上面的批量插入方式效率低,因为需要往数据库中insert100次;不如把100条记录先准备好,只insert一次, insert ... values(),(),... book_list = []
for i in range(100): # 这个过程中和数据库无关,只是实例化出了100个Book对象(因为没有 save() )
book_obj = Book(title="book_%s"%i,price=i*i)
book_list.append(book_obj)
# bulk_create():批量插入数据
Book.objects.bulk_create(book_list) # 效果就是:一条insert后面有100条数据 :param request:
:return:
""" book_list = Book.objects.all() # .objects.all():相当于一个 生成器,并不是一次性把数据从数据库全部取了出来 # Paginator(object_list,per_page):第一个参数是对象列表,第二个是每页显示多少条数据
paginator = Paginator(book_list,3) # 得到一个Paginator分页器对象 # paginator的属性
# print("count:",paginator.count) # paginator.count:统计Book_list里面有多少条数据
# print("num_pages:",paginator.num_pages) # paginator.num_pages:总共有多少页
# print("page_range:",paginator.page_range) # paginator.page_range:页码的列表 # count: 100
# num_pages: 13
# page_range: range(1, 14) # range(1,14) 是因为range顾头不顾尾 """
# 显示某一页具体数据的两种方式
page1 = paginator.page(1) # 第一页的page对象;page1可进行迭代处理
print("objects_list",page1.object_list) # page1.object_list:这一页所有的model记录对象;QuerySet类型 # page1也可进行遍历
for i in page1:
print(i) # 所以想要显示某一页的具体数据可以通过 page1.object_list 或者 遍历 page1 这两种方法
""" # 为了不把页码写死,需要动态的传入页码
current_page_num = int(request.GET.get("page", 1)) # get中的1表示默认获取到的值 # page_range:用于在模板中渲染多少个的页码的变量
# 固定显示的最大页码数为11页
if paginator.num_pages > 11:
# 如果总页码数大于11,则固定显示11页 # 如果当前页为最前面的5个, 则要让 page_range 固定为 range(1,12)
if current_page_num - 5 < 1:
page_range = range(1,12)
# 如果当前页为最后面的5个, 则要让 page_range 固定为 range(paginator.num_pages-10,paginator.num_pages+1) (即最后面的11个页码)
elif current_page_num + 5 > paginator.num_pages:
page_range = range(paginator.num_pages-10,paginator.num_pages+1)
else: # 中间的情况
page_range = range(current_page_num-5,current_page_num+6)
else:
# 如果小于11页,就显示全部页码
page_range = paginator.page_range # 如果页码错误(current_page_num不在有效页码范围之内),就让其显示第一页
try: current_page = paginator.page(current_page_num) # 当前页 """
# page对象的方法:
print(current_page.has_next()) # page.has_next():是否有下一页
print(current_page.next_page_number()) # page.next_page_number(): 下一页的页码
print(current_page.has_previous()) # 是否有上一页
print(current_page.previous_page_number()) # 上一页的页码
""" except EmptyPage as e:
current_page = paginator.page(1) return render(request,"index.html",locals())

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<ul>
{#此时不要循环所有数据(book_list),而是只循环当前页的数据 #}
{% for book in current_page %}
<li>{{ book.title }}:{{ book.price }}</li>
{% endfor %} </ul> <nav aria-label="Page navigation">
<ul class="pagination">
{# 另一种方法:直接利用 current_page.has_previous 和 current_page.previous_page_number #}
{# 先判断它有没有上一页 #}
{% if current_page.has_previous %}
<li>
{# 通过过滤器让 current_page_num 减1(加 -1);这是一种方法 #}
{# <a href="?page={{ current_page_num|add:-1 }}" aria-label="Previous">#} <a href="?page={{ current_page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{# 如果没有上一页,则让该li标签 disabled #}
{% else %}
<li class="disabled">
<a href="" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% endif %} {# 循环页码总数,添加分页器的页数 #}
{# 但为了只显示固定数量的页码数,我们应该只循环page_range这个变量,而不是所有的页码 #}
{# {% for item in paginator.page_range %}#}
{% for item in page_range %}
{% if current_page_num == item %}
{# a标签中的 herf 如果只有请求数据,那么默认的IP、端口和路径就是当前页面的 #}
<li class="active" ><a href="?page={{ item }}">{{ item }}</a></li>
{# 点击分页器中的某一页码,其颜色就会发生变化:在li标签中添加 class="active" #}
{% else %}
<li><a href="?page={{ item }}">{{ item }}</a></li>
{% endif %}
{% endfor %} {# <li><a href="?page={{ current_page_num|add:1 }}" aria-label="Next"><span aria-hidden="true">下一页</span></a></li>#}
{# 下一页同理: .has_next 和 next_page_num #}
{% if current_page.has_next %}
<li><a href="?page={{ current_page.next_page_number }}" aria-label="Next"><span aria-hidden="true">下一页</span></a></li>
{% else %}
<li class="disabled"><a href="" aria-label="Next"><span aria-hidden="true">下一页</span></a></li>
{% endif %}
</ul>
</nav> </body>
</html>

django组件 ---- forms组件

(1) forms组件之校验字段功能

urls.py

from django.contrib import admin
from django.urls import path from app01 import views urlpatterns = [
path('admin/', admin.site.urls),
path(r"reg/",views.reg)
]

views.py

from django.shortcuts import render,HttpResponse

# Create your views here.

# 导入forms组件
from django import forms
class UserForm(forms.Form): # 类名可以自己定义,但需要继承 forms.Form
# 字段名称 = 校验规则
# 校验规则都有一个 非空 规则
name = forms.CharField(min_length=4) # name这个字段必须是最少为4位的字符串
psw = forms.CharField(min_length=4)
r_psw = forms.CharField(min_length=4)
email = forms.EmailField() # forms.EmailField():邮箱校验规则
tel = forms.CharField() def reg(request):
if request.method == "POST": """
# forms组件的应用:
form = UserForm({"name":"neo","email":"123@qq.com","xx":"666naosid"}) # 把待校验的信息以字典的形式(字典的键值必须和类的字段一致)放入 UserForm中实例化一个对象;该对象有 is_valid() 的方法进行校验是否符合定义的校验规则
# 如果字典中的某个key在UserForm中的所有字段中不存在,且UserForm中的【所有】字段都校验正确,则这些不存在的key-value 不会对校验结果(form.is_valid())产生影响;但如果UserForm中不是【所有的】字段都校验正确,则 form.is_valid()返回 False
# 如: UserForm({"name":"neo123","email":"123@qq.com","xxx":"123465"}) 返回True,因为 name 和 email都校验正确(UserForm所有的字段);但 UserForm({"name":"neo123","xxx":"123465"}) 会返回 False
print(form.is_valid()) # is_valid() 返回Bool值 # UserForm中的字段如果没有被全部校验(如:字典是没有 "name"= "xxx" 等),则返回False,因为 为空匹配
if form.is_valid():
print(form.cleaned_data) # 如果 所有的字段都校验成功,则 form会有一个 cleaned_data 的属性, form.cleaned_data 是一个包含所有正确信息的字典(不包含不存在的字段,即不包含与UserForm无关的字段)
else: # 没有符合全部字段的校验规则 print(form.cleaned_data) # 把 form.is_valid() 在校验过程中发现的符合校验规则的key-value放入 form.cleaned_data 这个字典中
print(form.errors) # 把 form.is_valid() 在校验过程中发现的不符合校验规则的key-value(即错误信息)放入 form.errors 这个字典中;其数据类型可理解为一个字典,字典时的value是一个列表(django.forms.utils.ErrorList)放错误信息 """ # forms组件的校验功能
print(request.POST)
form = UserForm(request.POST) # request.POST(来自前端的form表单的name属性)本身就是一个字典,而且它的key和 UserForm的字段名一致(在reg.html中自己设置的);虽然 request.POST中有 csrf,但并不会影响校验结果(原因如上,只是多了一个无关的key-value而已) if form.is_valid():
print(form.cleaned_data)
else:
print(form.cleaned_data)
print(form.errors)
print(type(form.errors)) # <class 'django.forms.utils.ErrorDict'> # 所以能用字典的方法去处理 form.errors return HttpResponse("ok") return render(request,"reg.html")

reg.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form action="" method="post">
{% csrf_token %}
{# 为了form表单校验方便,表单控件是 name属性的值应该和forms组件(UserForm)中的字段一致 #}
<p>用户名 <input type="text" name="name"></p>
<p>密码 <input type="password" name="psw"></p>
<p>确认密码 <input type="password" name="r_psw"></p>
<p>邮箱 <input type="text" name="email"></p>
<p>电话 <input type="text" name="tel"></p>
<input type="submit"> </form> </body>
</html>

forms组件的渲染标签功能1:

还以上面的project为例

views.py

from django.shortcuts import render,HttpResponse

# Create your views here.

# 导入forms组件
from django import forms
class UserForm(forms.Form): # 类名可以自己定义,但需要继承 forms.Form
# 字段名称 = 校验规则
# 校验规则都有一个 非空 规则
name = forms.CharField(min_length=4) # CharField()可以渲染input标签
psw = forms.CharField(min_length=4)
r_psw = forms.CharField(min_length=4)
email = forms.EmailField() # EmailField() 也可以渲染input标签
tel = forms.CharField() def reg(request):
if request.method == "POST": if form.is_valid():
print(form.cleaned_data)
else:
print(form.cleaned_data)
print(form.errors)
print(type(form.errors)) return HttpResponse("ok") # forms组件渲染方式1
# 假如你不想自己去渲染 reg.html 中的form表单控件,你可以先用 UserForm 实例化一个对象 form,然后把这个 form 对象传到 render 中,最后在reg.html中利用 form对象去渲染 form表单控件
form1 = UserForm() # get请求方式时传入 render() reg.html 中去渲染 form 表单控件
return render(request,"reg.html",locals())

reg.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <h3>forms组件渲染方式1</h3> <form action="" method="post">
{% csrf_token %} <p>用户名
  {# 通过传进来的 UserForm 的对象 form1.字段的形式,可直接渲染出 input标签,并且 input标签的name属性值为 form1这个对象的 字段名#}
{{ form1.name }}
</p>
<p>密码 {{ form1.psw }}</p>
<p>确认密码 {{ form1.r_psw }}</p>
<p>邮箱 {{ form1.email }}</p>
<p>电话 {{ form1.tel }}</p>
{# CharField 校验规则能渲染 type="text"的input标签;EmailField 校验规则能渲染 type="email"的input标签#}
{# 字段非常多的时候可以用这种方式#}
<input type="submit">
</form> </body>
</html>

浏览器效果如下:

注意:forms组件的校验字段功能和渲染标签功能是两套功能;GET请求时进行渲染标签,POST时进行校验字段

forms组件的渲染标签功能2和3:

还以上面的project为例,views.py是要为UserForm这个类添加 label 属性

reg.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <h3>forms组件渲染方式2(推荐使用这种)</h3> <form action="" method="post">
{% csrf_token %} {# 也可以 for 循环 views.py 传进来的 form1这个对象,for循环这个form1对象时得到的是 每一个 field对象(字段对象,如渲染方式1中的 form1.name,form1.psw等)#}
{% for field in form1 %}
<p>
{# 字段对象有一个固有的属性 label,如 form1.psw.lable; 字段对象.label 在前端页面的展示效果会动态的跟随字段的名字而变化,如 form1.psw.label 在前端显示的input前的文字为 psw #}
{# 如果想让 label 属性显示中文,需要在 UserForm 中为每个字段添加 lable属性值 #}
<label for="">{{ field.label }}</label>
{# field.label的作用是让input标签前添加label标签(中文描述);field就是 form1.字段名 #}
{# 此时 field就是form1中的第一个字段对象 #}
{{ field }}
</p>
{% endfor %}
<input type="submit"> <h3>forms组件渲染方式方法3</h3>
<form action="" method="post">
{# 直接只写一个 form1.as_p #}
{{ form1.as_p }}
{# 不推荐这种写法,这种渲染方式得到的form表单控件的结构是固定的:<p><label></label><input></p>,直接就写死了 #}
</form> </form> </body>
</html>

views.py 中的UserForm:

# 导入forms组件
from django import forms
class UserForm(forms.Form): # 类名可以自己定义,但需要继承 forms.Form
# 字段名称 = 校验规则
# 校验规则都有一个 非空 规则
name = forms.CharField(min_length=4,label="用户名") # 为每个 字段添加 label属性
psw = forms.CharField(min_length=4,label="密码")
r_psw = forms.CharField(min_length=4,label="确认密码")
email = forms.EmailField(label="邮箱")
tel = forms.CharField(label="电话")

浏览器效果如下:

forms组件渲染错误信息

views.py

from django.shortcuts import render,HttpResponse

# Create your views here.

# 导入forms组件
from django import forms
class UserForm(forms.Form):
name = forms.CharField(min_length=4,label="用户名")
psw = forms.CharField(min_length=4,label="密码")
r_psw = forms.CharField(min_length=4,label="确认密码")
email = forms.EmailField(label="邮箱")
tel = forms.CharField(label="电话") def reg(request):
if request.method == "POST":
print(request.POST)
form1 = UserForm(request.POST) if form1.is_valid():
print(form1.cleaned_data)
else:
print(form1.cleaned_data)
print(form1.errors)
print(type(form1.errors)) # forms 组件渲染错误信息
# GET请求时的form1对象和POST请求时的form1对象是不一样的;GET的form1没有传数据(未邦定数据的forms组件对象),POST的form1传了数据(邦定数据的forms组件对象)
# 有错误信息时,依然把 reg.html 返回给前端;此时已输入的正确信息会在输入框中保留
return render(request,"reg.html",locals()) form1 = UserForm() # get请求方式时传入 render() reg.html 中去渲染 form 表单控件
return render(request,"reg.html",locals())

reg.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <h3>forms组件渲染错误信息</h3> {#form表单控件的 novalidate 表示:当提交表单时不对表单数据(输入)进行验证#}
<form action="" method="post" novalidate>
{% csrf_token %}
<p>
{{ form1.name.label }}
{# form1.字段不但能渲染出一个input标签,还能把 POST请求数据 在views.py 中过滤出来的正确信息 赋值给该 input 标签的value属性值;通过这种方式 在前端刷新页面时 已输入的正确信息能保留在输入框中 #}
{{ form1.name }} <span>{{ form1.name.errors.0 }}</span>
{# 每个字段对象都有一个 errors的属性;可通过 .errors.0 的方式 获取该错误信息 #}
{# GET请求时不会显示错误信息,因为此时没有 errors, .errors.0 找不到信息就在前端页面上显示为空 #}
</p>
<p>{{ form1.psw.label }} {{ form1.psw }}<span>{{ form1.psw.errors.0 }}</span></p>
<p>{{ form1.r_psw.label }} {{ form1.r_psw }}<span>{{ form1.r_psw.errors.0 }}</span></p>
<p>{{ form1.email.label }} {{ form1.email }}<span>{{ form1.email.errors.0 }}</span></p>
<p>{{ form1.tel.label }} {{ form1.tel }}<span>{{ form1.tel.errors.0 }}</span></p> <input type="submit">
</form> </form> </body>
</html>

forms组件的参数配置

forms组件的参数是在 views.py中的 UserForm中进行配置的,如:

# forms组件的参数配置
from django import forms
from django.forms import widgets
class UserForm(forms.Form): name = forms.CharField(min_length=4,label="用户名",error_messages={"required":"该字段不能为空"},
widget=widgets.TextInput(attrs={"class":"form-control"})) # name这个字段必须是最少为4位的字符串 # 为每个 字段添加 label属性
psw = forms.CharField(min_length=4,label="密码",error_messages={"required":"该字段不能为空"},
widget=widgets.PasswordInput(attrs={"class":"form-control"}))
r_psw = forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},
widget=widgets.PasswordInput(attrs={"class":"form-control"}))
email = forms.EmailField(label="邮箱",widget=widgets.EmailInput(attrs={"class":"form-control"}),
error_messages={"required": "该字段不能为空", "invalid": "邮箱格式错误"}) # forms.EmailField():邮箱校验规则
tel = forms.CharField(label="电话",widget=widgets.TextInput(attrs={"class":"form-control"}),error_messages={"required":"该字段不能为空"}) """
1. widget = widgets.TextInput():通过 添加属性 widget 能够控制渲染出来的input标签的 type 属性值,如: widget = widgets.TextInput() 表示渲染出 type="text"的input标签(默认值), widget= widgets.PasswordInput():text="passwrod" 的 input 标签,widget=widgets.EmailInput(): text="email" 的 input 标签
2. widget = widgets.TextInput(attrs={"class":"form-control"}):widget = widgets.TextInput()等参数中添加 attrs={"属性名":"属性值"} 能为渲染出来的input标签 添加特定的属性,如:widget = widgets.TextInput(attrs={"class":"form-control"}) 表示为渲染出来的 input标签添加 class="form-control"
3. error_messages={}:表示控制错误信息,如 error_messages={"required":"该字段不能为空","invalid":"格式错误"},"required"是“非空错误”的key,"invalid"是“格式错误”的key
"""

reg.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body> <div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h3>forms组件的参数配置</h3> <form action="" method="post" novalidate>
{% csrf_token %}
<p>
{{ form1.name.label }}
{{ form1.name }} <span>{{ form1.name.errors.0 }}</span>
</p>
<p>{{ form1.psw.label }} {{ form1.psw }}<span>{{ form1.psw.errors.0 }}</span></p>
<p>{{ form1.r_psw.label }} {{ form1.r_psw }}<span>{{ form1.r_psw.errors.0 }}</span></p>
<p>{{ form1.email.label }} {{ form1.email }}<span>{{ form1.email.errors.0 }}</span></p>
<p>{{ form1.tel.label }} {{ form1.tel }}<span>{{ form1.tel.errors.0 }}</span></p> <input type="submit" class="btn btn-default">
</form>
</div>
</div>
</div> </body>
</html>

局部钩子和全局钩子:

views.py

from django.shortcuts import render

# forms组件的参数配置
from django import forms
# 配置参数需要导入 widgets
from django.forms import widgets # 钩子需要导入 ValidationError
from django.core.exceptions import NON_FIELD_ERRORS,ValidationError from app01.models import UserInfo class UserForm(forms.Form): name = forms.CharField(min_length=4,label="用户名",error_messages={"required":"该字段不能为空"},
widget=widgets.TextInput(attrs={"class":"form-control"})) # name这个字段必须是最少为4位的字符串 # 为每个 字段添加 label属性
psw = forms.CharField(min_length=4,label="密码",error_messages={"required":"该字段不能为空"},
widget=widgets.PasswordInput(attrs={"class":"form-control"}))
r_psw = forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},
widget=widgets.PasswordInput(attrs={"class":"form-control"}))
email = forms.EmailField(label="邮箱",widget=widgets.EmailInput(attrs={"class":"form-control"}),
error_messages={"required": "该字段不能为空", "invalid": "邮箱格式错误"}) # forms.EmailField():邮箱校验规则
tel = forms.CharField(label="电话",widget=widgets.TextInput(attrs={"class":"form-control"}),error_messages={"required":"该字段不能为空"})
# 按照局部钩子校验字段
def clean_name(self): # 只能叫 clean_字段名
# 根据源码可知, 能执行 clean_字段 方法,说明已经通过了上面的 字段=校验规则 的校验 # 校验用户名是否重名
val = self.cleaned_data.get("name")
# 从数据库中读取数据
ret = UserInfo.objects.filter(name=val) if not ret:
return val # 根据源码可知, return的 val 依然是 name 字段对应的值
else:
raise ValidationError("用户名已注册") # 抛出的异常名必须是 ValidationError;抛出的错误会放到 错误字典中 def clean_tel(self):
# 校验手机号是否为11位
val = self.cleaned_data.get("tel")
print(val)
if len(val) == 11:
return val # 如果手机号为11位,通过校验,则把手机号原封不动返回
else:
raise ValidationError("手机号必须为11位") # 一次校验里面用到多个校验的字段,就不能再用 上面的局部钩子方法,因为局部钩子方法一次只能校验一个字段;此时应该用全局钩子
# clean():全局钩子;其它所有的校验规则校验完之后,才会走 clean()
def clean(self):
# 校验 psw 和 r_psw 是否一致
psw = self.cleaned_data.get("psw")
r_psw = self.cleaned_data.get("r_psw") # 先判断字段是否通过 字段校验和局部钩子,如果没有,则不进行全局钩子校验
if psw and r_psw:
if psw == r_psw:
return self.cleaned_data # 通过全局钩子校验,则把 cleaned_data 原封返回
else:
raise ValidationError("两次密码不一致!") # 全局钩子的错误字典的形式:{"__all__":[....]},其key是 "__all__";这个异常类型不能通过 字段 获取到 else: # 没通过字段校验和局部钩子,则把 干净的数据 clean_data 原封不动返回
return self.cleaned_data def reg(request):
if request.method == "POST":
print(request.POST)
form1 = UserForm(request.POST) if form1.is_valid():
print(form1.cleaned_data)
else:
print(form1.cleaned_data)
print(form1.errors)
print(type(form1.errors)) # 先把全局钩子的异常类型获取到
err = form1.errors.get("__all__") # 获取全局钩子的错误信息
# 同时要在 reg.html 中专门把此错误信息放到 r_psw后面
return render(request,"reg.html",locals())
form1 = UserForm()
return render(request,"reg.html",locals())

reg.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body> <div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h3>forms组件的参数配置</h3> <form action="" method="post" novalidate>
{% csrf_token %}
<p>
{{ form1.name.label }}
{{ form1.name }} <span>{{ form1.name.errors.0 }}</span>
</p>
<p>{{ form1.psw.label }} {{ form1.psw }}<span>{{ form1.psw.errors.0 }}</span></p>
<p>{{ form1.r_psw.label }}
{{ form1.r_psw }}
<span>{{ form1.r_psw.errors.0 }}</span>
{# err.0 表示获取第一个错误信息;err:列表的形式;不在 views.py中直接 form1.errors.get("__all__")[0] 是防止报错 #}
<span>{{ err.0 }}</span></p>
<p>{{ form1.email.label }} {{ form1.email }}<span>{{ form1.email.errors.0 }}</span></p>
<p>{{ form1.tel.label }} {{ form1.tel }}<span>{{ form1.tel.errors.0 }}</span></p> <input type="submit" class="btn btn-default">
</form>
</div>
</div>
</div> </body>
</html>

Django:(5)分页器 & forms组件的更多相关文章

  1. [Django高级之forms组件]

    [Django高级之forms组件] forms组件之校验字段 # 第一步:定义一个类,继承forms.Form # 第二步:在类中写字段,要校验的字段,字段属性就是校验规则 # 第三步:实例化得到一 ...

  2. django中的forms组件

    form介绍 用户需要向后端提交一些数据时,我们常常把这些数据放在一个form表单里,采用form标签,里面包含一些input等标签把用户的数据提交给后端. 在给后端提交数据的时候,我们常常也需要对于 ...

  3. Django基础之forms组件中的ModelForm组件

    Django的model form组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样 ...

  4. django中的forms组件(权限信息校验,增删改查)

    1.用处 1.用户请求数据验证 2.自动生成错误信息 3.打包用户提交的正确信息 4.如果其中有一个错误了,其他的正确,则保留上次输入的内容 5.自动创建input标签并可以设置样式 6.基于form ...

  5. Django框架的forms组件与一些补充

    目录 一.多对多的三种创建方式 1. 全自动 2. 纯手撸(了解) 3. 半自动(强烈推荐) 二.forms组件 1. 如何使用forms组件 2. 使用forms组件校验数据 3. 使用forms组 ...

  6. forms组件补充与ModelForm简单使用与cookie与session

    目录 forms组件钩子函数 forms组件字段参数 字段参数 validators详解 choices详解 widget详解 forms组件字段类型 ModelForm简单使用 cookie与ses ...

  7. Django学习——分页器基本使用、分页器终极用法、forms组件之校验字段、forms组件之渲染标签、forms组件全局钩子,局部钩子

    内容 1 分页器基本使用 2 分页器终极用法 3 forms组件之校验字段 1 前端 <!DOCTYPE html> <html lang="en"> &l ...

  8. django之分页器、多对多关系、form校验组件

    批量插入数据 bulk_create # 1.往书籍表中插入数据 1000 # for i in range(1000): # 这种插入方式 效率极低 # models.Book.objects.cr ...

  9. Django序列化组件与数据批量操作与简单使用Forms组件

    目录 SweetAlert前端插件 Django自带的序列化组件 批量数据操作 分页器与推导流程 Forms组件之创建 Forms组件之数据校验 Forms组件之渲染标签 Forms组件之信息展示 S ...

随机推荐

  1. 【先定一个小目标】dotnet core 命令详解

    本篇博客来了解一下dotnet这个神奇的命令.我会依次对dotnet,dotnet new,dotnet restore,dotnet build,dotnet test,dotnet run,dot ...

  2. 设置当前导航栏(navigationController)的标题

    一般在有导航navigationController的情况下,要设置页面的标题很简单 self.title = @"测试"; 也可以 self.navigationItem.tit ...

  3. hihocoder 神奇字符串

    思路: 暴力,模拟. 实现: #include <iostream> #include <algorithm> #include <cstdio> #include ...

  4. Angular jsonp 同源策略的问题

    引用:http://www.cnblogs.com/dengzy/p/5388357.html 说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决 ...

  5. Android开源项目:GifView——Android显示GIF动画

    下载:http://code.google.com/p/gifview/downloads/list 简介:android中现在没有直接显示gif的view,只能通过mediaplay来显示,且还常常 ...

  6. Wamp搭建的服务器登录的时候出现Access denied for user 'hello'@'localhost' (using password: YES)

    想用自己电脑做一个服务器,然后就选择了Wamp,本来一切顺利,可是到登录的时候却出现了问题,出现了 Access denied for user 'hello'@'localhost' (using ...

  7. jQuery.ajax() 设置 Headers 中的 Accept 内容

    jQuery.ajax() 如何设置 Headers 中的 Accept 内容   其实很简单,首先如果是常见类型,则请直接设置 dataType 属性 $.ajax({ dataType: &quo ...

  8. (转)淘淘商城系列——SSM框架整合之逆向工程

    http://blog.csdn.net/yerenyuan_pku/article/details/72758590 我们知道在开发中有些工作是非常耗时但是又没有什么技术含量的,比如创建mapper ...

  9. SolidWorks的文件类型

    零件模板 *.prtdot装配体模板 *.asmdot工程图模板 *.drwdot颜色文件 *.sldclr曲线文件 *.sldcrv复制设定向导文件 *.sldreg零件文件:prt sldprtF ...

  10. CAD参数绘制直径标注(com接口)

    主要用到函数说明: _DMxDrawX::DrawDimDiametric 绘制一个直径标注.详细说明如下: 参数 说明 DOUBLE dChordPointX 在被标注的曲线上的第一个点X值 DOU ...