效果图:

分页部分代码:

  1. # 1.分页处理
  2. all_count = self.model_class.objects.all().count()
  3. query_params = request.GET.copy() # 深copy
  4. query_params._mutable = True # query_params默认不可修改
  5.  
  6. pager = Pagination(
  7. current_page=request.GET.get('page'),
  8. all_count=all_count,
  9. base_url=request.path_info,
  10. query_params=query_params,
  11. per_page_data=self.per_page_data,
  12. )
  13. data_list = self.model_class.objects.all()[pager.start:pager.end]
  14.  
  15. context = {
  16. 'data_list': data_list,
  17. 'header_list': header_list,
  18. 'body_list': body_list,
  19. 'pager': pager,
  20. }

一、分页功能

stark/utils/pagination.py

  1. """
  2. 分页器
  3. """
  4.  
  5. class Pagination(object):
  6. def __init__(self, current_page, all_count, base_url, query_params, per_page_data=20, display_page_number=11):
  7. """
  8. 分页初始化
  9. :param current_page: 当前页码
  10. :param all_count: 数据库总条数
  11. :param base_url: 基础URL
  12. :param query_params: Querydict对象,内部含所有当前URL的原条件
  13. :param per_page_data: 每页显示数据条数
  14. :param display_page_number: 页面上最多显示的页码数量
  15. """
  16. self.base_url = base_url
  17. try:
  18. self.current_page = int(current_page)
  19. if self.current_page <= 0:
  20. raise Exception()
  21. except Exception as e:
  22. self.current_page = 1
  23.  
  24. self.all_count = all_count
  25. self.query_params = query_params
  26. self.per_page_data = per_page_data
  27. self.display_page_number = display_page_number
  28. real_page_number, remainder = divmod(self.all_count, self.per_page_data)
  29. if remainder != 0:
  30. real_page_number += 1
  31. self.real_page_number = real_page_number
  32. half_page_number = int(self.display_page_number / 2)
  33. self.half_page_number = half_page_number
  34.  
  35. @property
  36. def start(self):
  37. """
  38. 数据获取值起始索引
  39. :return:
  40. """
  41. return (self.current_page - 1) * self.per_page_data
  42.  
  43. @property
  44. def end(self):
  45. """
  46. 数据获取值结束索引
  47. :return:
  48. """
  49. return self.current_page * self.per_page_data
  50.  
  51. def page_html(self):
  52. """
  53. 生成HTML页码
  54. :return:
  55. """
  56. # 如果数据真实页码数小于11,则显示真实页码数
  57. if self.real_page_number < self.display_page_number:
  58. pager_start = 1
  59. pager_end = self.real_page_number
  60. else:
  61. # 真实页码数超过11
  62. if (self.current_page + self.half_page_number) > self.real_page_number:
  63. pager_start = self.real_page_number - self.display_page_number + 1
  64. pager_end = self.real_page_number
  65. else:
  66. pager_start = self.current_page - self.half_page_number
  67. pager_end = self.current_page + self.half_page_number
  68.  
  69. page_list = []
  70.  
  71. if self.current_page <= 1:
  72. prev_page = '<li><a href="#">上一页</a></li>'
  73. else:
  74. self.query_params['page'] = self.current_page - 1
  75. prev_page = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url, self.query_params.urlencode())
  76. page_list.append(prev_page)
  77.  
  78. for page_num in range(pager_start, pager_end + 1):
  79. self.query_params['page'] = page_num
  80. if self.current_page == page_num:
  81. show_page_num = '<li class="active"><a href="%s?%s">%s</a></li>' % (
  82. self.base_url, self.query_params.urlencode(), page_num)
  83. else:
  84. show_page_num = '<li><a href="%s?%s">%s</a></li>' % (
  85. self.base_url, self.query_params.urlencode(), page_num)
  86. page_list.append(show_page_num)
  87.  
  88. if self.current_page == self.real_page_number:
  89. next_page = '<li><a href="#">下一页</a></li>'
  90. else:
  91. self.query_params['page'] = self.current_page + 1
  92. next_page = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.query_params.urlencode())
  93. page_list.append(next_page)
  94. page_str = ''.join(page_list)
  95. return page_str

二、Strak组件

stark/service/core_func.py

  1. from types import FunctionType
  2.  
  3. from django.urls import re_path
  4. from django.utils.safestring import mark_safe
  5. from django.shortcuts import HttpResponse, render, reverse
  6.  
  7. from stark.utils.pagination import Pagination
  8.  
  9. def get_choice_text(title, field):
  10. """
  11. 对于Stark组件中定义列时,choice如果想要显示中文信息,调用此方法即可。
  12. :param title: 希望页面显示的表头
  13. :param field: 字段名称
  14. :return:
  15. """
  16.  
  17. def inner(self, obj=None, is_header=None):
  18. if is_header:
  19. return title
  20. method = "get_%s_display" % field
  21. return getattr(obj, method)()
  22. # GENDER_CHOICES = ((MALE, '男'),(FEMALE, '女'),)
  23. # 对于choice字段,如果想获取获取第二个值,可以通过:对象.get_字段名_display()
  24.  
  25. return inner
  26.  
  27. class StarkHandler(object):
  28. list_display = []
  29. per_page_data = 10
  30.  
  31. def __init__(self, site, model_class, prev):
  32. self.site = site
  33. self.model_class = model_class
  34. self.prev = prev
  35.  
  36. def display_edit(self, obj=None, is_header=None):
  37. """
  38. 自定义页面显示的列(表头和内容)
  39. :param obj:
  40. :param is_header:
  41. :return:
  42. """
  43. if is_header:
  44. return '编辑'
  45. name = '%s:%s' % (self.site.namespace, self.get_edit_url_name,)
  46. return mark_safe('<a href="%s">编辑</a>' % reverse(name, args=(obj.pk,)))
  47.  
  48. def display_delete(self, obj=None, is_header=None):
  49. if is_header:
  50. return '删除'
  51. name = '%s:%s' % (self.site.namespace, self.get_delete_url_name,)
  52. return mark_safe('<a href="%s">删除</a>' % reverse(name, args=(obj.pk,)))
  53.  
  54. def get_list_display(self):
  55. """
  56. 获取页面上应该显示的列,预留的自定义扩展,例如:以后根据用户的不同显示不同的列
  57. :return:
  58. """
  59. value = []
  60. value.extend(self.list_display)
  61. return value
  62.  
  63. def list_view(self, request):
  64. """
  65. 列表页面
  66. :param request:
  67. :return:
  68. """
  69.  
  70. # 1.分页处理
  71. all_count = self.model_class.objects.all().count()
  72. query_params = request.GET.copy() # 深copy
  73. query_params._mutable = True # query_params默认不可修改
  74.  
  75. pager = Pagination(
  76. current_page=request.GET.get('page'),
  77. all_count=all_count,
  78. base_url=request.path_info,
  79. query_params=query_params,
  80. per_page_data=self.per_page_data,
  81. )
  82. data_list = self.model_class.objects.all()[pager.start:pager.end]
  83.  
  84. list_display = self.get_list_display() # 会优先调用UserInfoHandler里的get_list_display()方法。
  85. # 2.1 处理表格的表头
  86. header_list = []
  87. if list_display:
  88. for field_or_func in list_display:
  89. if isinstance(field_or_func, FunctionType):
  90. verbose_name = field_or_func(self, obj=None, is_header=True)
  91. else:
  92. verbose_name = self.model_class._meta.get_field(field_or_func).verbose_name
  93. header_list.append(verbose_name)
  94. else:
  95. header_list.append(self.model_class._meta.model_name) # 如果用户没有填写list_display,就显示表名
  96.  
  97. # 2.2 处理表的内容
  98. body_list = []
  99. for obj in data_list:
  100. tr_list = []
  101. if list_display:
  102. for field_or_func in list_display:
  103. if isinstance(field_or_func, FunctionType):
  104. tr_list.append(field_or_func(self, obj, is_header=False))
  105. else:
  106. tr_list.append(getattr(obj, field_or_func))
  107. else:
  108. tr_list.append(obj) # 如果用户没有填写list_display,就显示表对象,所以表类要定义__str__方法
  109. body_list.append(tr_list)
  110.  
  111. context = {
  112. 'data_list': data_list,
  113. 'header_list': header_list,
  114. 'body_list': body_list,
  115. 'pager': pager,
  116. }
  117.  
  118. return render(request, 'stark/data_list.html', context)
  119.  
  120. def add_view(self, request):
  121. """
  122. 添加页面
  123. :param request:
  124. :return:
  125. """
  126. return HttpResponse('添加页面')
  127.  
  128. def edit_view(self, request, pk):
  129. """
  130. 编辑页面
  131. :param request:
  132. :return:
  133. """
  134. return HttpResponse('编辑页面')
  135.  
  136. def delete_view(self, request, pk):
  137. """
  138. 删除页面
  139. :param request:
  140. :param pk:
  141. :return:
  142. """
  143. return HttpResponse('删除页面')
  144.  
  145. def get_url_name(self, params):
  146. app_label, model_name = self.model_class._meta.app_label, self.model_class._meta.model_name
  147. if self.prev:
  148. return '%s_%s_%s_%s' % (app_label, model_name, self.prev, params)
  149. return '%s_%s_%s' % (app_label, model_name, params)
  150.  
  151. @property
  152. def get_list_url_name(self):
  153. """
  154. 获取列表页面URL的name
  155. :return:
  156. """
  157. return self.get_url_name('list')
  158.  
  159. @property
  160. def get_add_url_name(self):
  161. """
  162. 获取添加页面URL的name
  163. :return:
  164. """
  165. return self.get_url_name('add')
  166.  
  167. @property
  168. def get_edit_url_name(self):
  169. """
  170. 获取编辑页面URL的name
  171. :return:
  172. """
  173. return self.get_url_name('edit')
  174.  
  175. @property
  176. def get_delete_url_name(self):
  177. """
  178. 获取删除页面URL的name
  179. :return:
  180. """
  181. return self.get_url_name('delete')
  182.  
  183. def get_urls(self):
  184. patterns = [
  185. re_path(r'^list/$', self.list_view, name=self.get_list_url_name),
  186. re_path(r'^add/$', self.add_view, name=self.get_add_url_name),
  187. re_path(r'^edit/(\d+)/$', self.edit_view, name=self.get_edit_url_name),
  188. re_path(r'^delete/(\d+)/$', self.delete_view, name=self.get_delete_url_name),
  189. ]
  190.  
  191. patterns.extend(self.extra_urls())
  192. return patterns
  193.  
  194. def extra_urls(self):
  195. return []
  196.  
  197. class StarkSite(object):
  198. def __init__(self):
  199. self._registry = []
  200. self.app_name = 'stark'
  201. self.namespace = 'stark'
  202.  
  203. def register(self, model_class, handler_class=None, prev=None):
  204. """
  205. :param model_class: 是models中的数据库表对应的类。
  206. :param handler_class: 处理请求的视图函数所在的类
  207. :param prev: 生成URL的前缀
  208. :return:
  209. """
  210.  
  211. if not handler_class:
  212. handler_class = StarkHandler
  213. self._registry.append(
  214. {'model_class': model_class, 'handler': handler_class(self, model_class, prev), 'prev': prev})
  215.  
  216. def get_urls(self):
  217. patterns = []
  218. for item in self._registry:
  219. model_class = item['model_class']
  220. handler = item['handler']
  221. prev = item['prev']
  222. app_name, model_name = model_class._meta.app_label, model_class._meta.model_name
  223. if prev:
  224. patterns.append(
  225. re_path(r'^%s/%s/%s/' % (app_name, model_name, prev,), (handler.get_urls(), None, None)))
  226. else:
  227. patterns.append(re_path(r'^%s/%s/' % (app_name, model_name,), (handler.get_urls(), None, None)))
  228.  
  229. return patterns
  230.  
  231. @property
  232. def urls(self):
  233. return self.get_urls(), self.app_name, self.namespace
  234.  
  235. site = StarkSite()

三、业务处理

web/stark.py

  1. from stark.service.core_func import site, StarkHandler, get_choice_text
  2.  
  3. from web import models
  4.  
  5. class DepartmentHandler(StarkHandler):
  6. list_display = ['title']
  7.  
  8. class UserInfoHandler(StarkHandler):
  9. per_page_data = 1
  10. list_display = [
  11. 'name',
  12. get_choice_text('性别', 'gender'),
  13. get_choice_text('班级', 'classes'),
  14. 'age', 'email', 'department',
  15. StarkHandler.display_edit,
  16. StarkHandler.display_delete,
  17.  
  18. ]
  19.  
  20. site.register(models.Department, DepartmentHandler) # 给部门的url增加了前缀:/stark/web/department/private/
  21. site.register(models.UserInfo, UserInfoHandler)

四、模板渲染

  1. {% extends 'layout.html' %}
  2.  
  3. {% block content %}
  4. <div class="custom-container">
  5. <table class="table table-bordered">
  6. <thead>
  7. <tr>
  8. {% for item in header_list %}
  9. <th>{{ item }}</th>
  10. {% endfor %}
  11. </tr>
  12. </thead>
  13. <tbody>
  14. {% for row in body_list %}
  15. <tr>
  16. {% for ele in row %}
  17. <td>{{ ele }}</td>
  18. {% endfor %}
  19.  
  20. </tr>
  21. {% endfor %}
  22. </tbody>
  23. </table>
  24.  
  25. <!-- 分页 -->
  26. <nav>
  27. <ul class="pagination">
  28. {{ pager.page_html|safe }}
  29. </ul>
  30. </nav>
  31. <!-- 分页结束 -->
  32. </div>
  33. {% 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. cookie乱码处理 示例

    package com.log; import java.io.IOException; import java.net.URLEncoder; import java.util.ArrayList; ...

  2. Thinkphp 出现 “_CACHE_WRITE_ERROR” 错误的可能解决办法

    有可能是老毛病: Cache文件夹和里面的文件,php没有权限 解决办法: chmod -R 777 /.............../www/Cache

  3. check_mk插件 redis

    /usr/lib/check_mk_agent/plugins/mk_redis #!/bin/bash echo '<<<redis>>>' hosts=$(ne ...

  4. Docker cgroup.procs no space left on device

    环境:centos6 运行docker 时 错误提示: System error: write /sys/fs/cgroup/docker/01f5670fbee1f6687f58f3a943b1e1 ...

  5. April 17 2017 Week 16 Monday

    You will find that it is necessary to let things go; simply for the reason that they are heavy. 你会明白 ...

  6. IOS tableView的基本使用

    tableView  Style:Plain(头部标题 向上移 不会消失) tableView  Style:Grouped(头部标题 向上移 会 消失) #import "ViewCont ...

  7. Graylog安装操作

    Graylog安装操作 实验环境centos7.5系统  mem:4-8G       disk:50G 关闭selinux以及firewalld 一.准备环境 1.1.java环境 下载java的j ...

  8. InnoDB锁演示

    create table t1( c1 int(10) unsigned not null default '0', c2 int(10) unsigned not null default '0', ...

  9. 关于Linux部分版本无法安装Chrome的问题

    在想要yum安装Chrome浏览器后发现安装没有相应的包,在查询后得知Chrome已经对Redhat和Centos等部分版本停止支持, 所以这些新版的系统中直接安装就显得有些困难了,那么从网上找到了一 ...

  10. Bootstarp学习教程(7) 表单

    基本案例:“form-control”修饰的<input>.<textarea>和<select>元素都将被默认设置为width: 100%;表单控件包裹在&quo ...