自定义分页器的拷贝及使用html
校验性组件:form组件前端
组件有不少不少,就相似于功能模块python
class Pagination(object): def __init__(self, current_page, all_count, per_page_num=2, pager_count=11): """ 封装分页相关数据 :param current_page: 当前页 :param all_count: 数据库中的数据总条数 :param per_page_num: 每页显示的数据条数 :param pager_count: 最多显示的页码个数 """ try: current_page = int(current_page) except Exception as e: current_page = 1 if current_page < 1: current_page = 1 self.current_page = current_page self.all_count = all_count self.per_page_num = per_page_num # 总页码 all_pager, tmp = divmod(all_count, per_page_num) if tmp: all_pager += 1 self.all_pager = all_pager self.pager_count = pager_count self.pager_count_half = int((pager_count - 1) / 2) @property def start(self): return (self.current_page - 1) * self.per_page_num @property def end(self): return self.current_page * self.per_page_num def page_html(self): # 若是总页码 < 11个: if self.all_pager <= self.pager_count: pager_start = 1 pager_end = self.all_pager + 1 # 总页码 > 11 else: # 当前页若是<=页面上最多显示11/2个页码 if self.current_page <= self.pager_count_half: pager_start = 1 pager_end = self.pager_count + 1 # 当前页大于5 else: # 页码翻到最后 if (self.current_page + self.pager_count_half) > self.all_pager: pager_end = self.all_pager + 1 pager_start = self.all_pager - self.pager_count + 1 else: pager_start = self.current_page - self.pager_count_half pager_end = self.current_page + self.pager_count_half + 1 page_html_list = [] # 添加前面的nav和ul标签 page_html_list.append(''' <nav aria-label='Page navigation>' <ul class='pagination'> ''') first_page = '<li><a href="?page=%s">首页</a></li>' % (1) page_html_list.append(first_page) if self.current_page <= 1: prev_page = '<li class="disabled"><a href="#">上一页</a></li>' else: prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,) page_html_list.append(prev_page) for i in range(pager_start, pager_end): if i == self.current_page: temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,) else: temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,) page_html_list.append(temp) if self.current_page >= self.all_pager: next_page = '<li class="disabled"><a href="#">下一页</a></li>' else: next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,) page_html_list.append(next_page) last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,) page_html_list.append(last_page) # 尾部添加标签 page_html_list.append(''' </nav> </ul> ''') return ''.join(page_html_list)
1 """ 2 当咱们须要使用到非django内置的第三方功能或者组件代码的时候 3 咱们通常状况下会建立一个名为utils文件夹 在该文件夹内对模块进行功能性划分 4 utils能够在每一个应用下建立 具体结合实际状况 5 6 咱们到了后期封装代码的时候 再也不局限于函数 7 仍是尽可能朝面向对象去封装 8 9 咱们自定义的分页器是基于bootstrap样式来的 因此你须要提早导入bootstrap 10 bootstrap 版本 v3 11 jQuery 版本 v3 12 """ 13 # 后端 14 book_queryset = models.Book.objects.all() 15 current_page = request.GET.get('page',1) 16 all_count = book_queryset.count() 17 # 1 传值生成对象 18 page_obj = Pagination(current_page=current_page,all_count=all_count) 19 # 2 直接对总数据进行切片操做 20 page_queryset = book_queryset[page_obj.start:page_obj.end] 21 # 3 将page_queryset传递到页面 替换以前的book_queryset 22 23 24 # 前端 25 {% for book_obj in page_queryset %} 26 <p>{{ book_obj.title }}</p> 27 {% endfor %} 28 {#利用自定义分页器直接显示分页器样式#} 29 {{ page_obj.page_html|safe }} 30 31 """ 32 大家只须要掌握如何拷贝使用 以及大体的推导思路便可 33 """
1 """ 2 写一个注册功能 3 获取用户名和密码 利用form表单提交数据 4 在后端判断用户名和密码是否符合必定的条件 5 用户名中不能含有嘤嘤嘤 6 密码不能少于三位 7 8 如何符合条件须要你将提示信息展现到前端页面 9 """ 10 def ab_form(request): 11 back_dic = {'username':'','password':''} 12 if request.method == 'POST': 13 username = request.POST.get('username') 14 password = request.POST.get('password') 15 if '嘤嘤嘤' in username: 16 back_dic['username'] = '你嘤nm' 17 if len(password) < 3: 18 back_dic['password'] = '不能过短 很差!' 19 """ 20 不管是post请求仍是get请求 21 页面都可以获取到字典 只不过get请求来的时候 字典值都是空的 22 而post请求来以后 字典可能有值 23 """ 24 return render(request,'ab_form.html',locals()) 25 26 <form action="" method="post"> 27 <p>username: 28 <input type="text" name="username"> 29 <span style="color: red">{{ back_dic.username }}</span> 30 </p> 31 <p>password: 32 <input type="text" name="password"> 33 <span style="color: red">{{ back_dic.password }}</span> 34 </p> 35 <input type="submit" class="btn btn-info"> 36 </form> 37 38 39 """ 40 1.手动书写前端获取用户数据的html代码 渲染html代码 41 2.后端对用户数据进行校验 校验数据 42 3.对不符合要求的数据进行前端提示 展现提示信息 43 44 forms组件 45 可以完成的事情 46 1.渲染html代码 47 2.校验数据 48 3.展现提示信息 49 50 为何数据校验非要去后端 不能在前端利用js直接完成呢? 51 数据校验前端无关紧要 52 可是后端必需要有!!! 53 54 由于前端的校验是弱不由风的 你能够直接修改 55 或者利用爬虫程序绕过前端页面直接朝后端提交数据 56 57 购物网站 58 选取了货物以后 会计算一个价格发送给后端 若是后端不作价格的校验 59 60 实际是获取到用户选择的全部商品的主键值 61 而后在后端查询出全部商品的价格 再次计算一遍 62 若是跟前端一致 那么完成支付若是不一致直接拒绝 63 """
1 from django import forms 2 3 4 class MyForm(forms.Form): 5 # username字符串类型最小3位最大8位 6 username = forms.CharField(min_length=3,max_length=8) 7 # password字符串类型最小3位最大8位 8 password = forms.CharField(min_length=3,max_length=8) 9 # email字段必须符合邮箱格式 xxx@xx.com 10 email = forms.EmailField()
1 """ 2 1.测试环境的准备 能够本身拷贝代码准备 3 2.其实在pycharm里面已经帮你准备一个测试环境 4 python console 5 """ 6 from app01 import views 7 # 1 将带校验的数据组织成字典的形式传入便可 8 form_obj = views.MyForm({'username':'jason','password':'123','email':'123'}) 9 # 2 判断数据是否合法 注意该方法只有在全部的数据所有合法的状况下才会返回True 10 form_obj.is_valid() 11 False 12 # 3 查看全部校验经过的数据 13 form_obj.cleaned_data 14 {'username': 'jason', 'password': '123'} 15 # 4 查看全部不符合校验规则以及不符合的缘由 16 form_obj.errors 17 { 18 'email': ['Enter a valid email address.'] 19 } 20 # 5 校验数据只校验类中出现的字段 多传不影响 多传的字段直接忽略 21 form_obj = views.MyForm({'username':'jason','password':'123','email':'123@qq.com','hobby':'study'}) 22 form_obj.is_valid() 23 True 24 # 6 校验数据 默认状况下 类里面全部的字段都必须传值 25 form_obj = views.MyForm({'username':'jason','password':'123'}) 26 form_obj.is_valid() 27 False 28 """ 29 也就意味着校验数据的时候 默认状况下数据能够多传可是毫不可能少传 30 """
""" forms组件只会自动帮你渲染获取用户输入的标签(input select radio checkbox) 不能帮你渲染提交按钮 """ def index(request): # 1 先产生一个空对象 form_obj = MyForm() # 2 直接将该空对象传递给html页面 return render(request,'index.html',locals()) # 前端利用空对象作操做 <p>第一种渲染方式:代码书写极少,封装程度过高 不便于后续的扩展 通常状况下只在本地测试使用</p> {{ form_obj.as_p }} {{ form_obj.as_ul }} {{ form_obj.as_table }} <p>第二种渲染方式:可扩展性很强 可是须要书写的代码太多 通常状况下不用</p> <p>{{ form_obj.username.label }}:{{ form_obj.username }}</p> <p>{{ form_obj.password.label }}:{{ form_obj.password }}</p> <p>{{ form_obj.email.label }}:{{ form_obj.email }}</p> <p>第三种渲染方式(推荐使用):代码书写简单 而且扩展性也高</p> {% for form in form_obj %} <p>{{ form.label }}:{{ form }}</p> {% endfor %} """ label属性默认展现的是类中定义的字段首字母大写的形式 也能够本身修改 直接给字段对象加label属性便可 username = forms.CharField(min_length=3,max_length=8,label='用户名') """
1 """ 2 浏览器会自动帮你校验数据 可是前端的校验弱不由风 3 如何让浏览器不作校验 4 <form action="" method="post" novalidate> 5 """ 6 def index(request): 7 # 1 先产生一个空对象 8 form_obj = MyForm() 9 if request.method == 'POST': 10 # 获取用户数据而且校验 11 """ 12 1.数据获取繁琐 13 2.校验数据须要构形成字典的格式传入才行 14 ps:可是request.POST能够当作就是一个字典 15 """ 16 # 3.校验数据 17 form_obj = MyForm(request.POST) 18 # 4.判断数据是否合法 19 if form_obj.is_valid(): 20 # 5.若是合法 操做数据库存储数据 21 return HttpResponse('OK') 22 # 5.不合法 有错误 23 # 2 直接将该空对象传递给html页面 24 return render(request,'index.html',locals()) 25 26 {% for form in form_obj %} 27 <p> 28 {{ form.label }}:{{ form }} 29 <span style="color: red">{{ form.errors.0 }}</span> 30 </p> 31 {% endfor %} 32 33 """ 34 1.必备的条件 get请求和post传给html页面对象变量名必须同样 35 2.forms组件当你的数据不合法的状况下 会保存你上次的数据 让你基于以前的结果进行修改 36 更加的人性化 37 """ 38 # 针对错误的提示信息还能够本身自定制 39 class MyForm(forms.Form): 40 # username字符串类型最小3位最大8位 41 username = forms.CharField(min_length=3,max_length=8,label='用户名', 42 error_messages={ 43 'min_length':'用户名最少3位', 44 'max_length':'用户名最大8位', 45 'required':"用户名不能为空" 46 } 47 ) 48 # password字符串类型最小3位最大8位 49 password = forms.CharField(min_length=3,max_length=8,label='密码', 50 error_messages={ 51 'min_length': '密码最少3位', 52 'max_length': '密码最大8位', 53 'required': "密码不能为空" 54 } 55 ) 56 # email字段必须符合邮箱格式 xxx@xx.com 57 email = forms.EmailField(label='邮箱', 58 error_messages={ 59 'invalid':'邮箱格式不正确', 60 'required': "邮箱不能为空" 61 } 62 )
1 """ 2 在特定的节点自动触发完成响应操做 3 4 钩子函数在forms组件中就相似于第二道关卡,可以让咱们自定义校验规则 5 6 在forms组件中有两类钩子 7 1.局部钩子 8 当你须要给单个字段增长校验规则的时候可使用 9 2.全局钩子 10 当你须要给多个字段增长校验规则的时候可使用 11 """ 12 # 实际案例 13 14 # 1.校验用户名中不能含有666 只是校验username字段 局部钩子 15 16 # 2.校验密码和确认密码是否一致 password confirm两个字段 全局钩子 17 18 # 钩子函数 在类里面书写方法便可 19 # 局部钩子 20 def clean_username(self): 21 # 获取到用户名 22 username = self.cleaned_data.get('username') 23 if '666' in username: 24 # 提示前端展现错误信息 25 self.add_error('username','光喊666是不行滴~') 26 # 将钩子函数钩去出来数据再放回去 27 return username 28 29 # 全局钩子 30 def clean(self): 31 password = self.cleaned_data.get('password') 32 confirm_password = self.cleaned_data.get('confirm_password') 33 if not confirm_password == password: 34 self.add_error('confirm_password','两次密码不一致') 35 # 将钩子函数钩出来数据再放回去 36 return self.cleaned_data
label 给字段起名 error_messages 自定义报错信息 initial 设定默认值 required 控制字段是否必填 """ 1.字段没有样式 2.针对不一样类型的input如何修改 text password date radio checkbox ... """ widget=forms.widgets.PasswordInput(attrs={'class':'form-control c1 c2', 'username': 'jason'}) # 多个属性值的话 直接空格隔开便可 # 第一道关卡里面还支持正则校验 from django.core.validators import RegexValidator # 导入RegexValidator校验器模块 class MyForm(Form): user = fields.CharField( validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')], )
1 # radio 2 gender = forms.ChoiceField( 3 choices=((1, "男"), (2, "女"), (3, "保密")), 4 label="性别", 5 initial=3, 6 widget=forms.widgets.RadioSelect() 7 ) 8 # 单选select 9 hobby = forms.ChoiceField( 10 choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), 11 label="爱好", 12 initial=3, 13 widget=forms.widgets.Select() 14 ) 15 # 多选Select 16 hobby1 = forms.MultipleChoiceField( 17 choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), 18 label="爱好", 19 initial=[1, 3], 20 widget=forms.widgets.SelectMultiple() 21 ) 22 # 单选checkbox 23 keep = forms.ChoiceField( 24 label="是否记住密码", 25 initial="checked", 26 widget=forms.widgets.CheckboxInput() 27 ) 28 # 多选checkbox 29 hobby2 = forms.MultipleChoiceField( 30 choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), 31 label="爱好", 32 initial=[1, 3], 33 widget=forms.widgets.CheckboxSelectMultiple() 34 )
""" 今日考题 1.简述自定义分页器的使用 2.forms组件是干什么用的,它的主要功能有哪些功能,你可否具体说说每一个功能下都有哪些常常用到的方法及注意事项(越详细越好) 3..forms组件钩子函数是干什么用的,如何编写,请举例说明,除此以外forms组件还提供了哪些校验方法 """
1 """ 2 当你在项目中须要使用第三方的功能代码或者本身封装的一些功能代码 3 那么通常状况下都是会新建一个文件夹(utils)专门用来存储相关的代码 4 该文件夹既能够建在全局 也能够在每一个应用下都建立属于该应用独有的 5 6 封装代码的思路 7 1.先用最粗燥的代码完成功能 8 2.在功能完成的基础之上再去考虑优化 9 1.先由面条版封装成函数 10 2.再看看能不能封装成面向对象 11 并非说必定须要封装成面向对象的形式 要看状况 12 """ 13 # 代码无需掌握直接拷贝使用便可 14 # 后端使用 15 book_queryset = models.Book.objects.all() # 惰性查询 16 current_page = request.GET.get('page',1) 17 all_count = book_queryset.count() 18 page_obj = Pagenation(current_page=current_page,all_count=all_count) 19 page_queryset = book_queryset[page_obj.start:page_obj.end] 20 # 只须要将page_obj,page_queryset传递给html页面便可 21 22 # 前端使用(自定义分页器须要使用bootstrap) 23 {{ page_obj.page_html|safe }}
1 """ 2 1.渲染标签 3 2.校验数据 4 3.展现信息 5 """ 6 from django import forms 7 class MyForm(forms.Form): 8 username = forms.CharField(label='用户名',max_length=8,min_length=3) 9 10 # 校验数据 11 # 1 给类传字典 12 form_obj = MyForm({'username':'jason'}) 13 # 2 判读数据是否合法 14 form_obj.is_valid() # 只有全部的数据都符合条件才会为True 15 # 3 如何查看符合条件数据 16 form_obj.cleaned_data 17 # 4 如何查看不符合条件的以及缘由 18 form_obj.errors 19 # 5 forms类中全部的字段默认都是必填的 20 # 6 校验的数据能够多传可是不能少传 21 22 # 渲染标签 23 # 1 第一种 24 {{ form_obj.as_p }} 25 # 2 第二种 26 {{form_obj.username.label}}{{form_obj.username}} 27 # 3 第三种(经常使用) 28 {% for form in form_obj %} 29 {{ form.label }}:{{ form }} 30 <span>{{ form.errors.0 }}</span> 31 {% endfor %} 32 33 34 # 展现错误信息 35 {% for form in form_obj %} 36 {{ form.label }}:{{ form }} 37 <span>{{ form.errors.0 }}</span> 38 {% endfor %} 39 40 username = forms.CharField(label='用户名', 41 max_length=8, 42 min_length=3, 43 error_messages={ 44 'required':"用户名必填", 45 ... 46 } 47 48 )
1 """ 2 局部钩子 3 校验单个字段 4 全局钩子 5 校验多个字段 6 """ 7 def clean_username(self): 8 self.add_error('username','用户名错误') 9 return username 10 11 def clean(self): 12 return self.cleaned_data
1 label 别名 2 min_length 最短 3 max_length 最长 4 required 能不能为空 5 initial 默认值 6 error_messages 错误提示 7 validators 正则 8 widget 9 """ 10 针对字段的校验有不少种 11 1.最简单的min_length 12 2.正则validator 13 3.钩子函数 14 15 前端的校验的无关紧要 可是后端的校验一点都不能含糊 16 17 form表单如何取消浏览器自动校验功能 18 <form novalidate></form> 19 """
1 """ 2 radio 3 checkbox 4 select 5 了解整理到博客中 以后使用再来拷贝 6 https://www.cnblogs.com/Dominic-Ji/p/9240365.html 7 """
""" 1.整理今日内容到博客 2.利用forms组件完成用户注册完整功能 """
""" 1.整理今日内容到博客 2.利用forms组件完成用户注册完整功能 """数据库