1 分页器终极用法
1.1 后端
def books_page(request):
current_num = int(request.GET.get('page_num', 1))
book_list = models.Books.objects.all()
paginator = Paginator(book_list, 20)
try:
page = paginator.page(current_num)
except Exception as e:
current_num = 1
page = paginator.page(current_num)
if paginator.num_pages > 11:
if current_num - 5 < 1:
page_range = range(1, 12)
elif current_num + 5 > paginator.num_pages:
page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
else:
page_range = range(current_num - 5, current_num + 6)
else:
page_range = paginator.page_range
return render(request, 'book_page.html', locals())
1.2 前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<script src="/static/jquery-3.3.1.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">图书列表展示</h3>
</div>
<div class="panel-body">
<table class="table table-striped">
<thead>
<tr>
<th>id</th>
<th>书名</th>
<th>价格</th>
<th>出版社</th>
</tr>
</thead>
<tbody>
{% for book in page.object_list %}
<tr>
<td>{{ book.id }}</td>
<td>{{ book.name }}</td>
<td>{{ book.price }}</td>
<td>{{ book.publish }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="text-center">
<nav aria-label="Page navigation">
<ul class="pagination">
{% if page.has_previous %}
<li>
<a href="/books_page/?page_num={{ page.previous_page_number }}"
aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{% for foo in page_range %}
{% if current_num == foo %}
<li class="active"><a href="/books_page/?page_num={{ foo }}">{{ foo }}</a></li>
{% else %}
<li><a href="/books_page/?page_num={{ foo }}">{{ foo }}</a></li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li>
<a href="/books_page/?page_num={{ 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>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
</div>
</body>
</html>
# 第一步:定义一个类,继承forms.Form
# 第二步:在类中写字段,要校验的字段,字段属性就是校验规则
# 第三步:实例化得到一个Form对象,把要校验的数据传入
# 第四步:调用register_form.is_valid()校验,校验通过就是True
# 第五步:校验通过有register_form.cleaned_data
# 第六步:校验不通过 register_form.errors
#定义类
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
class RegisterForm(forms.Form):
name = forms.CharField(max_length=8, min_length=3, label='用户名')
password = forms.CharField(max_length=8, min_length=3, label='密码')
re_password = forms.CharField(max_length=8, min_length=3, label='确认密码')
email = forms.EmailField(label='邮箱')
#在视图中使用
register_form = RegisterForm(request.POST)
if register_form.is_valid():
# 校验通过,存
# 取出校验通过的数据
print('校验通过')
print(register_form.cleaned_data)
else:
# 校验不通过
print('校验不通过')
print(register_form.errors)
3.1 渲染方式一
<h2>通过form自动渲染一</h2>
<form action="" method="post">
<p>用户名 {{ form.name }}</p>
<p>密码 {{ form.password }}</p>
<p>确认密码 {{ form.re_password }}</p>
<p>邮箱 {{ form.email }}</p>
<input type="submit" value="提交">
</form>
3.2 渲染方式二
<h2>通过form自动渲染二(基本用这种)</h2>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form action="" method="post" novalidate>
{% for item in form %}
<div class="form-group">
<p>{{ item.label }}{{ item }} <span style="color: red">{{ item.errors.0 }}</span></p>
</div>
{% endfor %}
<input type="submit" value="提交"><span style="color: red">{{ error }}</span>
</form>
</div>
</div>
</div>
3.3 渲染方式三
<h2>通过form自动渲染三</h2>
<form action="" method="post">
{{ form.as_p }}
{# {{ form.as_table }}#}
{# {{ form.as_ul }}#}
</form>
4.1 前端
<h2>通过form自动渲染二(基本用这种)</h2>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form action="" method="post" novalidate>
{% for item in form %}
<div class="form-group">
<p>{{ item.label }}{{ item }} <span style="color: red">{{ item.errors.0 }}</span></p>
</div>
{% endfor %}
<input type="submit" value="提交"><span style="color: red">{{ error }}</span>
</form>
</div>
</div>
</div>
4.3 后端
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
class RegisterForm(forms.Form):
name = forms.CharField(max_length=8, min_length=3, label='用户名',
error_messages={'max_length': '最长为8', 'min_length': '最短为3'},
widget=widgets.TextInput(attrs={'class':'form-control'}))
password = forms.CharField(max_length=8, min_length=3, label='密码',
error_messages={'required': '该字段必填'},
widget=widgets.PasswordInput(attrs={'class':'form-control'}))
re_password = forms.CharField(max_length=8, min_length=3, label='确认密码',
widget=widgets.PasswordInput(attrs={'class':'form-control'}))
email = forms.EmailField(label='邮箱',
error_messages={'required': '必填', 'invalid': '必须是邮箱格式'},
widget=widgets.TextInput(attrs={'class':'form-control'}))
name = forms.CharField(max_length=8, min_length=3, label='用户名',error_messages={'max_length': '最长为8', 'min_length': '最短为3'},widget=widgets.TextInput(attrs={'class':'form-control'}))
6.1 后端
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
class RegisterForm(forms.Form):
name = forms.CharField(max_length=8, min_length=3, label='用户名',
error_messages={'max_length': '最长为8', 'min_length': '最短为3'},
widget=widgets.TextInput(attrs={'class':'form-control'}))
password = forms.CharField(max_length=8, min_length=3, label='密码',
error_messages={'required': '该字段必填'},
widget=widgets.PasswordInput(attrs={'class':'form-control'}))
re_password = forms.CharField(max_length=8, min_length=3, label='确认密码',
widget=widgets.PasswordInput(attrs={'class':'form-control'}))
email = forms.EmailField(label='邮箱',
error_messages={'required': '必填', 'invalid': '必须是邮箱格式'},
widget=widgets.TextInput(attrs={'class':'form-control'}))
def clean_name(self):#name字段的局部钩子
# 校验名字不能以sb开头
name=self.cleaned_data.get('name')
if name.startswith('sb'):
# 校验不通过,必须抛异常,
raise ValidationError('不能以sb开头')
else:#校验通过,返回name对应的值
return name
def clean(self): # 全局钩子
password=self.cleaned_data.get('password')
re_password=self.cleaned_data.get('re_password')
if re_password==password:
#校验通过
return self.cleaned_data
else:
raise ValidationError('两次密码不一致')
from app01 import models
def register(request):
if request.method == 'GET':
# 生成一个空form对象
register_form = RegisterForm()
return render(request, 'register.html', {'form': register_form})
else:
# 实例化得到对象,传入要校验的数据
# register_form=RegisterForm(data=request.POST)
register_form = RegisterForm(request.POST)
if register_form.is_valid():
# 校验通过,存
# 取出校验通过的数据
print('校验通过')
print(register_form.cleaned_data)
register_form.cleaned_data.pop('re_password')
models.User.objects.create(**register_form.cleaned_data)
return HttpResponse('ok')
else:
# 校验不通过
print('校验不通过')
print(register_form.errors)
error=register_form.errors.get('__all__')[0]
print(type(register_form.errors.as_json))
from django.forms.utils import ErrorDict
# name_error=register_form.errors.get('name')[0]
return render(request, 'register.html', {'form': register_form,'error':error})
6.2 前端
<h2>通过form自动渲染二(基本用这种)</h2>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form action="" method="post" novalidate>
{% for item in form %}
<div class="form-group">
<p>{{ item.label }}{{ item }} <span style="color: red">{{ item.errors.0 }}</span></p>
</div>
{% endfor %}
<input type="submit" value="提交"><span style="color: red">{{ error }}</span>
</form>
</div>
</div>
</div>