五.4--分页之封装成类及使用

之前的效果中,分页的代码都是在一个视图函数里面,如果别的页面页要用到的话,我们还要复制一遍,这样代码显的很low---所以我们可以对它进行封装成类,到时候就可以用类的对象即可调用,我们可以在我们项目下面新建一个文件夹utils,在新建一个pagination.py文件,把我们分页的代码写到里面。

1.pagination.py中:

"""
分页器
"""
from django.utils.safestring import mark_safe
class Pagination: #把分页封装成一个类
def __init__(self, request, all_count, per_num=10, max_show=11):#把跟值有关的都放初始函数中,并传参,那后边使用就要加self
# 基本的URL self.base_url = request.path_info # 当前页码 try: self.current_page = int(request.GET.get('page', 1)) if self.current_page <= 0: self.current_page = 1 except Exception as e: self.current_page = 1 # 最多显示的页码数 self.max_show = max_show half_show = max_show // 2 # 每页显示的数据条数 self.per_num = per_num # 总数据量 self.all_count = all_count # 总页码数 self.total_num, more = divmod(all_count, per_num) if more: self.total_num += 1 # 总页码数小于最大显示数:显示总页码数 if self.total_num <= max_show: self.page_start = 1 self.page_end = self.total_num else: # 总页码数大于最大显示数:最多显示11个 if self.current_page <= half_show: self.page_start = 1 self.page_end = max_show elif self.current_page + half_show >= self.total_num: self.page_end = self.total_num self.page_start = self.total_num - max_show + 1 else: self.page_start = self.current_page - half_show self.page_end = self.current_page + half_show @property    #@property装饰器就是负责把一个方法变成属性调用的 def start(self): return (self.current_page - 1) * self.per_num @property def end(self):#起始页码要根据当前页码和每页显示的页码个数进行计算,所以单独写方法
return self.current_page * self.per_num @property def show_li(self):#终止页码要根据当前页码和每页显示的页码个数进行计算,所以单独写方法
# 存放li标签的列表 html_list = [] first_li = '
  • 首页
  • '.format(self.base_url) html_list.append(first_li) if self.current_page == 1: prev_li = '
  • <<
  • ' else:#---self.base_url是传给href prev_li = '
  • <<
  • '.format(self.current_page - 1, self.base_url) html_list.append(prev_li) for num in range(self.page_start, self.page_end + 1): if self.current_page == num: li_html = '
  • {0}
  • '.format(num, self.base_url) else: li_html = '
  • {0}
  • '.format(num, self.base_url) html_list.append(li_html) if self.current_page == self.total_num: next_li = '
  • >>
  • ' else: next_li = '
  • >>
  • '.format(self.current_page + 1, self.base_url) html_list.append(next_li) last_li = '
  • 尾页
  • '.format(self.total_num, self.base_url) html_list.append(last_li) return mark_safe(''.join(html_list))

      

    2.views.py中:

    from django.shortcuts import render, redirect
    from django.contrib import auth
    from crm.forms import RegForm
    from crm import models
    from django.utils.safestring import mark_safe
    from utils.pagination import Pagination   #导入自己封装的分页器
    
    def login(request):
        err_msg = ''
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            obj = auth.authenticate(request, username=username, password=password)
            if obj:
                return redirect('/index/')
            err_msg = '用户名或密码错误'
        
        return render(request, 'login.html', {'err_msg': err_msg})
    
    # 注册
    def reg(request):
        form_obj = RegForm()
        if request.method == 'POST':
            form_obj = RegForm(request.POST)
            if form_obj.is_valid():
                # 创建新用户
                # 方法一
                # form_obj.cleaned_data.pop('re_password')
                # models.UserProfile.objects.create_user(**form_obj.cleaned_data)
                
                # 方法二
                obj = form_obj.save()
                obj.set_password(obj.password)
                obj.save()
                
                return redirect('/login/')
        return render(request, 'reg.html', {'form_obj': form_obj})
    
    
    # 展示客户列表页
    def customer_list(request):
        all_customer = models.Customer.objects.all()
        page = Pagination(request, all_customer.count())#实例化调用分页器并传数据的长度参数
        
        return render(request, 'crm/customer_list.html',
                      {"all_customer": all_customer[page.start:page.end], 'pagination':page.show_li})#前端直接调用渲染pagination即可
    
    # 测试分页
    # 测试数据页
    users = [{'name': 'alex{}'.format(i), 'pwd': 'alexdsb{}'.format(i)} for i in range(1, 302)]
    def user_list(request):
        page = Pagination(request, len(users))#实例化后就可调用分页器,并传入总数据量参数
        
        return render(request, 'user_list.html',
                      {
                          "data": users[page.start:page.end],    调用分页器中的start和end方法                  
                          'html_str': page.show_li  #前端直接调用渲染html_str即可
                      })
    

      

    3.页面效果:

    五.4--分页之封装成类及使用_第1张图片

    4.别的页面如何调用我的分页器

    那同样的别的页面也能调用我的分页器了,如customer_list.html客户列表页:代码在上述views.py中也写了,但因要让此分页器适用任何不同基础url的页面,所以要定义基础的url是动态的,(我此前的所有效果中基础url都是写死的,写/user_list/)如下图就是基础url不一样的

    五.4--分页之封装成类及使用_第2张图片

     

     

     五.4--分页之封装成类及使用_第3张图片

     

     

    (1)注意分页器pagination.py中要加 一个base_url基础url的参数,并定义基础url。

    # 基本的URL
    self.base_url = request.path_info

    (2)且要在pagination.py的show_li方法中的生成li标签里传base_url

    (3)在views.py中某个想要使用你分页器的页面的视图函数中要实例化你的分页器类,如下:

    def customer_list(request):#此页面要使用分页器
    all_customer = models.Customer.objects.all()
    page = Pagination(request, all_customer.count())#实例化调用分页器并传数据的长度参数
        return render(request, 'crm/customer_list.html',
    {"all_customer": all_customer[page.start:page.end], 'pagination': page.show_li})

    (4)再把user_list.html中的分页代码块复制到customer_list.html中即可:如下

    五.4--分页之封装成类及使用_第4张图片

     

     最后效果如下:

    五.4--分页之封装成类及使用_第5张图片

     

     

     



    你可能感兴趣的:(五.4--分页之封装成类及使用)