在讲自定义分页之前,先讲一个简单的。
在模板语言中还有一些特殊的存在,比如这个:
def tpl4(request): name = "asdf123456" return render(request, 'tpl4.html', {'name': name})
tpl4.html:
<body> {{ name }} {{ name|upper }} </body>
运行后:
这些我们只需了解,但应该要学会自定义这种操作:
自定义simple_tag:
1.在某个app目录下创建一个名为templatetags文件夹(必须为这个名字)
2.在文件夹内创建py文件写入函数(任意取名)‘
3.写函数之前还有一个固定的格式,不能变,然后记得要在settings里面注册app
例:创建了一个st.py
from django import template from django.utils.safestring import mark_safe register = template.Library() @register.simple_tag def func(a1, a2): return a1 + a2
4.在html文件中固定格式:
{% load st %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% func 6 7 %} </body> </html>
这里就实现了一个加法功能。
自定义filter:
和上面这个差不过,不过它只能传2个参数:
from django import template from django.utils.safestring import mark_safe register = template.Library() @register.filter def func(a1, a2): return a1 + a2
html中:
<body> {{ "fun"|func:"ction" }} </body>
看似这种远不如上面那种好用,不过,它也有它的优点:
{% if "fun"|func:"ction" %} {% endif %}
它可以用于if判断中,不过simple_tag不支持
自定义分页:
这里做一个简单的分页示例:
views.py加入:
LIST = [] for i in range(109): LIST.append(i) def user_list(request): current_page = request.GET.get('p', 1) current_page = int(current_page) start = (current_page - 1) * 10 end = current_page * 10 data = LIST[start: end] all_count = len(LIST) count, y = divmod(all_count, 10) if y: count += 1 page_list = [] for i in range(1, count + 1): if i == current_page: temp = '<a class="page active" href="/user_list/?p=%s">%s</a>' % (i, i) else: temp = '<a class="page" href="/user_list/?p=%s">%s</a>' % (i, i) page_list.append(temp) from django.utils.safestring import mark_safe page_str = "".join(page_list) page_str = mark_safe(page_str) # 为了防止XSS攻击 return render(request, 'user_list.html', {'li': data, 'page_str': page_str})
user_list.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .pagination .page{ display: inline-block; padding: 5px; background-color: aqua; margin: 5px; } .pagination .active{ background-color: brown; color: white; } </style> </head> <body> <ul> {% for item in li %} {% include 'li.html' %} {% endfor %} </ul> <div class="pagination"> {{ page_str }} </div> </body> </html>
顺便用下上一篇的知识:
li.html:
<li>{{ item }}</li>
效果这样:
选中的那个会变成红色的。
这里做到了,但是如果数据过多,就显得不好了。
完善:
LIST = [] for i in range(1009): LIST.append(i) def user_list(request): current_page = request.GET.get('p', 1) current_page = int(current_page) per_page_count = 10 start = (current_page - 1) * per_page_count end = current_page * per_page_count data = LIST[start: end] all_count = len(LIST) total_count, y = divmod(all_count, per_page_count) if y: total_count += 1 page_list = [] page_num = 11 if total_count <= page_num: start_index = 1 end_index = total_count+1 else: if current_page <= (page_num+1)/2: start_index = 1 end_index = page_num+1 else: start_index = current_page-(page_num-1)/2 end_index = current_page+(page_num+1)/2 if (current_page+(page_num-1)/2) > total_count: end_index = total_count+1 start_index = total_count-(page_num-1) if int(current_page) == 1: prev = '<a class="page" href="javascript:void(0);">上一页</a>' else: prev = '<a class="page" href="/user_list/?p=%s">上一页</a>' % (current_page-1) page_list.append(prev) for i in range(int(start_index), int(end_index)): if i == current_page: temp = '<a class="page active" href="/user_list/?p=%s">%s</a>' % (i, i) else: temp = '<a class="page" href="/user_list/?p=%s">%s</a>' % (i, i) page_list.append(temp) if current_page == total_count: nex = '<a class="page" href="javascript:void(0);">下一页</a>' else: nex = '<a class="page" href="/user_list/?p=%s">下一页</a>' % (current_page+1) page_list.append(nex) jump = ''' <input type="text"/><a οnclick='jumpTo(this, "/user_list/?p=");'>GO</a> <script> function jumpTo(ths,base){ var val = ths.previousSibling.value; location.href = base + val; } </script> ''' page_list.append(jump) from django.utils.safestring import mark_safe page_str = "".join(page_list) page_str = mark_safe(page_str) # 为了防止XSS攻击 return render(request, 'user_list.html', {'li': data, 'page_str': page_str})
完善后的效果:
发现代码量很大,可以对它进行封装:
创一个utils文件夹,新建一个pagination.py
class Page: def __init__(self, current_page, data_count, per_page_count=10, page_num=7): self.current_page = current_page self.data_count = data_count self.per_page_count = per_page_count self.page_num = page_num def start(self): return (self.current_page - 1) * self.per_page_count def end(self): return self.current_page * self.per_page_count def all_count(self): v, y = divmod(self.data_count, self.per_page_count) if y: v += 1 return v def page_str(self, base_url): page_list = [] if self.all_count() <= self.page_num: start_index = 1 end_index = self.all_count() + 1 else: if self.current_page <= (self.page_num + 1) / 2: start_index = 1 end_index = self.page_num + 1 else: start_index = self.current_page - (self.page_num - 1) / 2 end_index = self.current_page + (self.page_num + 1) / 2 if (self.current_page + (self.page_num - 1) / 2) > self.all_count(): end_index = self.all_count() + 1 start_index = self.all_count() - (self.page_num - 1) if int(self.current_page) == 1: prev = '<a class="page" href="javascript:void(0);">上一页</a>' else: prev = '<a class="page" href="%s?p=%s">上一页</a>' % (base_url, self.current_page - 1) page_list.append(prev) for i in range(int(start_index), int(end_index)): if i == self.current_page: temp = '<a class="page active" href="%s?p=%s">%s</a>' % (base_url, i, i) else: temp = '<a class="page" href="%s?p=%s">%s</a>' % (base_url, i, i) page_list.append(temp) if self.current_page == self.all_count(): nex = '<a class="page" href="javascript:void(0);">下一页</a>' else: nex = '<a class="page" href="%s?p=%s">下一页</a>' % (base_url, self.current_page + 1) page_list.append(nex) jump = ''' <input type="text"/><a οnclick='jumpTo(this, "%s?p=");'>GO</a> <script> function jumpTo(ths,base){ var val = ths.previousSibling.value; location.href = base + val; } </script> ''' % (base_url,) page_list.append(jump) from django.utils.safestring import mark_safe page_str = "".join(page_list) page_str = mark_safe(page_str) # 为了防止XSS攻击 return page_str
在views.py里面这样写即可:
from utils import pagination LIST = [] for i in range(1009): LIST.append(i) def user_list(request): current_page = request.GET.get('p', 1) current_page = int(current_page) page_obj = pagination.Page(current_page, len(LIST)) data = LIST[page_obj.start():page_obj.end()] page_str = page_obj.page_str("/user_list/") return render(request, 'user_list.html', {'li': data, 'page_str': page_str})