效果图:

分页部分代码:

# 1.分页处理
all_count = self.model_class.objects.all().count()
query_params = request.GET.copy() # 深copy
query_params._mutable = True # query_params默认不可修改 pager = Pagination(
current_page=request.GET.get('page'),
all_count=all_count,
base_url=request.path_info,
query_params=query_params,
per_page_data=self.per_page_data,
)
data_list = self.model_class.objects.all()[pager.start:pager.end] context = {
'data_list': data_list,
'header_list': header_list,
'body_list': body_list,
'pager': pager,
}

一、分页功能

stark/utils/pagination.py

"""
分页器
""" class Pagination(object):
def __init__(self, current_page, all_count, base_url, query_params, per_page_data=20, display_page_number=11):
"""
分页初始化
:param current_page: 当前页码
:param all_count: 数据库总条数
:param base_url: 基础URL
:param query_params: Querydict对象,内部含所有当前URL的原条件
:param per_page_data: 每页显示数据条数
:param display_page_number: 页面上最多显示的页码数量
"""
self.base_url = base_url
try:
self.current_page = int(current_page)
if self.current_page <= 0:
raise Exception()
except Exception as e:
self.current_page = 1 self.all_count = all_count
self.query_params = query_params
self.per_page_data = per_page_data
self.display_page_number = display_page_number
real_page_number, remainder = divmod(self.all_count, self.per_page_data)
if remainder != 0:
real_page_number += 1
self.real_page_number = real_page_number
half_page_number = int(self.display_page_number / 2)
self.half_page_number = half_page_number @property
def start(self):
"""
数据获取值起始索引
:return:
"""
return (self.current_page - 1) * self.per_page_data @property
def end(self):
"""
数据获取值结束索引
:return:
"""
return self.current_page * self.per_page_data def page_html(self):
"""
生成HTML页码
:return:
"""
# 如果数据真实页码数小于11,则显示真实页码数
if self.real_page_number < self.display_page_number:
pager_start = 1
pager_end = self.real_page_number
else:
# 真实页码数超过11
if (self.current_page + self.half_page_number) > self.real_page_number:
pager_start = self.real_page_number - self.display_page_number + 1
pager_end = self.real_page_number
else:
pager_start = self.current_page - self.half_page_number
pager_end = self.current_page + self.half_page_number page_list = [] if self.current_page <= 1:
prev_page = '<li><a href="#">上一页</a></li>'
else:
self.query_params['page'] = self.current_page - 1
prev_page = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url, self.query_params.urlencode())
page_list.append(prev_page) for page_num in range(pager_start, pager_end + 1):
self.query_params['page'] = page_num
if self.current_page == page_num:
show_page_num = '<li class="active"><a href="%s?%s">%s</a></li>' % (
self.base_url, self.query_params.urlencode(), page_num)
else:
show_page_num = '<li><a href="%s?%s">%s</a></li>' % (
self.base_url, self.query_params.urlencode(), page_num)
page_list.append(show_page_num) if self.current_page == self.real_page_number:
next_page = '<li><a href="#">下一页</a></li>'
else:
self.query_params['page'] = self.current_page + 1
next_page = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.query_params.urlencode())
page_list.append(next_page)
page_str = ''.join(page_list)
return page_str

二、Strak组件

stark/service/core_func.py

from types import FunctionType

from django.urls import re_path
from django.utils.safestring import mark_safe
from django.shortcuts import HttpResponse, render, reverse from stark.utils.pagination import Pagination def get_choice_text(title, field):
"""
对于Stark组件中定义列时,choice如果想要显示中文信息,调用此方法即可。
:param title: 希望页面显示的表头
:param field: 字段名称
:return:
""" def inner(self, obj=None, is_header=None):
if is_header:
return title
method = "get_%s_display" % field
return getattr(obj, method)()
# GENDER_CHOICES = ((MALE, '男'),(FEMALE, '女'),)
# 对于choice字段,如果想获取获取第二个值,可以通过:对象.get_字段名_display() return inner class StarkHandler(object):
list_display = []
per_page_data = 10 def __init__(self, site, model_class, prev):
self.site = site
self.model_class = model_class
self.prev = prev def display_edit(self, obj=None, is_header=None):
"""
自定义页面显示的列(表头和内容)
:param obj:
:param is_header:
:return:
"""
if is_header:
return '编辑'
name = '%s:%s' % (self.site.namespace, self.get_edit_url_name,)
return mark_safe('<a href="%s">编辑</a>' % reverse(name, args=(obj.pk,))) def display_delete(self, obj=None, is_header=None):
if is_header:
return '删除'
name = '%s:%s' % (self.site.namespace, self.get_delete_url_name,)
return mark_safe('<a href="%s">删除</a>' % reverse(name, args=(obj.pk,))) def get_list_display(self):
"""
获取页面上应该显示的列,预留的自定义扩展,例如:以后根据用户的不同显示不同的列
:return:
"""
value = []
value.extend(self.list_display)
return value def list_view(self, request):
"""
列表页面
:param request:
:return:
""" # 1.分页处理
all_count = self.model_class.objects.all().count()
query_params = request.GET.copy() # 深copy
query_params._mutable = True # query_params默认不可修改 pager = Pagination(
current_page=request.GET.get('page'),
all_count=all_count,
base_url=request.path_info,
query_params=query_params,
per_page_data=self.per_page_data,
)
data_list = self.model_class.objects.all()[pager.start:pager.end] list_display = self.get_list_display() # 会优先调用UserInfoHandler里的get_list_display()方法。
# 2.1 处理表格的表头
header_list = []
if list_display:
for field_or_func in list_display:
if isinstance(field_or_func, FunctionType):
verbose_name = field_or_func(self, obj=None, is_header=True)
else:
verbose_name = self.model_class._meta.get_field(field_or_func).verbose_name
header_list.append(verbose_name)
else:
header_list.append(self.model_class._meta.model_name) # 如果用户没有填写list_display,就显示表名 # 2.2 处理表的内容
body_list = []
for obj in data_list:
tr_list = []
if list_display:
for field_or_func in list_display:
if isinstance(field_or_func, FunctionType):
tr_list.append(field_or_func(self, obj, is_header=False))
else:
tr_list.append(getattr(obj, field_or_func))
else:
tr_list.append(obj) # 如果用户没有填写list_display,就显示表对象,所以表类要定义__str__方法
body_list.append(tr_list) context = {
'data_list': data_list,
'header_list': header_list,
'body_list': body_list,
'pager': pager,
} return render(request, 'stark/data_list.html', context) def add_view(self, request):
"""
添加页面
:param request:
:return:
"""
return HttpResponse('添加页面') def edit_view(self, request, pk):
"""
编辑页面
:param request:
:return:
"""
return HttpResponse('编辑页面') def delete_view(self, request, pk):
"""
删除页面
:param request:
:param pk:
:return:
"""
return HttpResponse('删除页面') def get_url_name(self, params):
app_label, model_name = self.model_class._meta.app_label, self.model_class._meta.model_name
if self.prev:
return '%s_%s_%s_%s' % (app_label, model_name, self.prev, params)
return '%s_%s_%s' % (app_label, model_name, params) @property
def get_list_url_name(self):
"""
获取列表页面URL的name
:return:
"""
return self.get_url_name('list') @property
def get_add_url_name(self):
"""
获取添加页面URL的name
:return:
"""
return self.get_url_name('add') @property
def get_edit_url_name(self):
"""
获取编辑页面URL的name
:return:
"""
return self.get_url_name('edit') @property
def get_delete_url_name(self):
"""
获取删除页面URL的name
:return:
"""
return self.get_url_name('delete') def get_urls(self):
patterns = [
re_path(r'^list/$', self.list_view, name=self.get_list_url_name),
re_path(r'^add/$', self.add_view, name=self.get_add_url_name),
re_path(r'^edit/(\d+)/$', self.edit_view, name=self.get_edit_url_name),
re_path(r'^delete/(\d+)/$', self.delete_view, name=self.get_delete_url_name),
] patterns.extend(self.extra_urls())
return patterns def extra_urls(self):
return [] class StarkSite(object):
def __init__(self):
self._registry = []
self.app_name = 'stark'
self.namespace = 'stark' def register(self, model_class, handler_class=None, prev=None):
"""
:param model_class: 是models中的数据库表对应的类。
:param handler_class: 处理请求的视图函数所在的类
:param prev: 生成URL的前缀
:return:
""" if not handler_class:
handler_class = StarkHandler
self._registry.append(
{'model_class': model_class, 'handler': handler_class(self, model_class, prev), 'prev': prev}) def get_urls(self):
patterns = []
for item in self._registry:
model_class = item['model_class']
handler = item['handler']
prev = item['prev']
app_name, model_name = model_class._meta.app_label, model_class._meta.model_name
if prev:
patterns.append(
re_path(r'^%s/%s/%s/' % (app_name, model_name, prev,), (handler.get_urls(), None, None)))
else:
patterns.append(re_path(r'^%s/%s/' % (app_name, model_name,), (handler.get_urls(), None, None))) return patterns @property
def urls(self):
return self.get_urls(), self.app_name, self.namespace site = StarkSite()

三、业务处理

web/stark.py

from stark.service.core_func import site, StarkHandler, get_choice_text

from web import models

class DepartmentHandler(StarkHandler):
list_display = ['title'] class UserInfoHandler(StarkHandler):
per_page_data = 1
list_display = [
'name',
get_choice_text('性别', 'gender'),
get_choice_text('班级', 'classes'),
'age', 'email', 'department',
StarkHandler.display_edit,
StarkHandler.display_delete, ] site.register(models.Department, DepartmentHandler) # 给部门的url增加了前缀:/stark/web/department/private/
site.register(models.UserInfo, UserInfoHandler)

四、模板渲染

{% extends 'layout.html' %}

{% block content %}
<div class="custom-container">
<table class="table table-bordered">
<thead>
<tr>
{% for item in header_list %}
<th>{{ item }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in body_list %}
<tr>
{% for ele in row %}
<td>{{ ele }}</td>
{% endfor %} </tr>
{% endfor %}
</tbody>
</table> <!-- 分页 -->
<nav>
<ul class="pagination">
{{ pager.page_html|safe }}
</ul>
</nav>
<!-- 分页结束 -->
</div>
{% endblock content %}

stark组件(7):增加分页功能的更多相关文章

  1. 搭建自己的博客(九):使用shell模式批量添加博客文章并增加分页功能

    想做个博客分页功能,但是没有太多的文章.所以使用shell命令行创建多篇文章. 1.打开pycharm下的terminal终端 python manage.py shell # 打开python终端 ...

  2. stark组件开发之添加功能实现

    添加功能,还是使用, form 组件来完成!  并且 完成添加之后,需要保留原搜索条件. def memory_url(self): '''用于反向生成url, 并且携带,get请求的参数,跳转到下一 ...

  3. stark组件开发之分页

    """ 分页组件 """ class Pagination(object): def __init__(self, current_page ...

  4. stark组件开发之编辑功能实现

    编辑功能.和添加一样! 唯一不同的就是, 需要编辑一个指定的  记录.这就需要,在列表页面, 渲染编辑的时候,添加一个 id 值: class UserInfoHandler(StartHandler ...

  5. Android开发 ---基本UI组件7 :分页功能、适配器、滚动条监听事件

    效果图: 1.activity_main.xml 描述: 定义了一个按钮 <?xml version="1.0" encoding="utf-8"?> ...

  6. spring和mybatis集成,自动生成model、mapper,增加mybatis分页功能

    软件简介 Spring是一个流行的控制反转(IoC)和面向切面(AOP)的容器框架,在java webapp开发中使用广泛.http://projects.spring.io/spring-frame ...

  7. 分页功能的实现——Jdbc && JSP

    @目录 什么是分页 ? 两个子模块功能的问题分析 和 解决方案 有条件查和无条件查询的影响 和 解决方案 项目案例: mysql + commons-dbutils+itcast-tools+Base ...

  8. 《JavaWeb从入门到改行》分页功能的实现

    @目录 什么是分页 ? 两个子模块功能的问题分析 和 解决方案 有条件查和无条件查询的影响 和 解决方案 项目案例: mysql + commons-dbutils+itcast-tools+Base ...

  9. crm项目-stark组件

    ###############  admin基本认识和常用的定制功能    ############### stark组件 对admin的基本认识 1,就是一个app,嵌入到了django里面,你可以 ...

随机推荐

  1. Swift UI开发初探 (转)

    原文地址:http://www.tairan.com/archives/6600 关于Swift语法,可以参考<Apple Swift编程语言入门教程> 效果如下: 开发环境 Xcode6 ...

  2. jQueryMobile(三)

    五].jQueryMobile工具栏 头部.尾部的定位:data-position='inline' 默认data-position='fixed' 固定在头部/尾部data-fullscreen=' ...

  3. python网络编程-paramiko模块

    paramiko模块 该模块基于SSH用于连接远程服务器并执行相关操作 参考文档 SSHClient 用于连接远程服务器并执行命令 import paramiko #创建SSH对象 ssh = par ...

  4. SourceTree Win10 安装过程及配置

    SourceTree 是一款拥有可视化界面的项目版本控制软件,适用于git项目管理,同时它集成了 git flow 工作流程,对于不熟悉 git 命令的初学者来说,可以通过 SourceTree 快速 ...

  5. python JSON性能测试与simplejson对比

    简单测试了一下,如果用JSON,也就是python2.6以上自带的json处理库,效率还算可以: 1K的数据,2.9GHz的CPU,单核下每秒能dump:36898次.大约是pyamf的5倍.但数据量 ...

  6. c++的bind1st()与bind2nd() 二元算子转一元算子

    bind1st()和bind2nd()是两个函数,用于将二元算子转成一元算子. 何谓二元算子? 比如< > =等等这些就是二元算子,即需要两个操作数的运算符. 何谓一元算子? 比如++ - ...

  7. 笨办法学Python(十七)

    习题 17: 更多文件操作 现在让我们再学习几种文件操作.我们将编写一个 Python 脚本,将一个文件中的内容拷贝到另外一个文件中.这个脚本很短,不过它会让你对于文件操作有更多的了解. from s ...

  8. PHP : url中出现乱码问题

    例子: 在html中,将数据传到url中 当我点击“提交回复”后,跳转页面中将显示: 我们获取这个参数: 但是由于传过来的参数是中文,url会进行自动的解析成二进制的代码,那我们后台接受到的数据是解析 ...

  9. java 中的Number类 Character类 String类 StringBuffer类 StringBuilder类

    1. Number类 Java语言为每一个内置数据类型提供了对应的包装类.所有的包装类(Integer.Long.Byte.Double.Float.Short)都是抽象类Number的子类.这种由编 ...

  10. 最长公共单词,类似LCS,(POJ2250)

    题目链接:http://poj.org/problem?id=2250 解题报告: 1.状态转移方程: ; i<=len1; i++) { ; j<=len2; j++) { dp[i][ ...