Django 自定义分页组件

Django+前端\django\myweb\blog\utils\pagination.py

"""
自定义的分页组件
"""
from django.utils.safestring import mark_safe
import copy

class Pagination(object):

    def __init__(self, request, queryset, page_size=15, page_param="page", plus=5):
        """
        :param request: 请求的对象
        :param queryset: 符合条件的数据(根据此数据进行分页处理)
        :param page_size: 每页显示多少条数据
        :param page_param: 获取在URL中传递的分页参数, 例如: /pretty/list/?page=21
        :param plus: 页码显示前几页后几页
        """

        # 防止搜索出结果进行翻页时,URL参数没有了搜索参数
        """request.GET  对象    QueryDict类型
        1.默认QueryDict不允许被修改 _mutable=False
            request.GET._mutable = True
        2.设置值
            request.GET.setlist("q",[12])    # q=12
            request.GET.setlist("page",[1, 3])   # page=1&page=1
            request.GET.setlist("page",[12])   # page=1
        3.调用urlencode方法,可以拼接
            paramString = request.GET.urlencode()
            print(paramString) "q=12&page=12"
        """
        query_dict = copy.deepcopy(request.GET)
        query_dict._mutable = True
        self.query_dict = query_dict
        # print(request.GET.urlencode())

        # 判断 page 页码是否合理
        page = request.GET.get(page_param, "1")
        if page.isdecimal():
            page = int(page)
        else:
            page = 1
        # print(page, type(page))

        # # 如果不是整数
        # page = int(request.GET.get(page_param, "1"))
        # if type(page) != int:
        #     # 强制让页码为1
        #     page = 1

        self.page_param = page_param
        self.page = page
        self.page_size = page_size

        self.start = (page - 1) * page_size
        self.end = page * page_size

        # 每页展示的数据行数
        self.page_queryset = queryset[self.start:self.end]

        total_count = queryset.count()
        total_page_count, div = divmod(total_count, page_size)
        if div:
            total_page_count += 1

        self.total_page_count = total_page_count
        self.plus = plus

    def html(self):
        # 计算显示当前页的前5页,后5页

        # 如果数据小于等于11页时
        if self.total_page_count <= 2 * self.plus + 1:
            self.start_page = 1
            self.end_page = self.total_page_count
        else:
            # 如果数据大于11页时
            # 当前页小于等于5时
            if self.page <= self.plus:
                self.start_page = 1
                self.end_page = 2 * self.plus + 1
            else:
                # 当前页大于5时
                # 如果大当前页+5 > 总页码
                if self.page + self.plus > self.total_page_count:
                    self.end_page = self.total_page_count
                    self.start_page = self.total_page_count - 2 * self.plus
                else:
                    self.start_page = self.page - self.plus
                    self.end_page = self.page + self.plus

        page_str_list = []

        # 跳到首页
        # self.head_page = '?page={}'.format(1)
        self.query_dict.setlist(self.page_param, [1])
        # print(self.query_dict.urlencode())
        self.head_page = '<li><a href="?{}" aria-label="Previous"><span aria-hidden="true">首页</span></a></li>'.format(self.query_dict.urlencode())
        page_str_list.append(self.head_page)

        # 上一页
        if self.page == 1:
            self.query_dict.setlist(self.page_param, [1])
            prev = '<li><a href="?{}" aria-label="Previous"><span aria-hidden="true">上一页</span></a></li>'.format(self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [self.page - 1])
            prev = '<li><a href="?{}" aria-label="Previous"><span aria-hidden="true">上一页</span></a></li>'.format(self.query_dict.urlencode())
        page_str_list.append(prev)

        for i in range(self.start_page, self.end_page + 1):
            if i == self.page:
                self.query_dict.setlist(self.page_param, [i])
                ele = '<li class="active"><a href="?{}">{}<span class="sr-only">(current)</span></a></li>'.format(self.query_dict.urlencode(), i)
            else:
                self.query_dict.setlist(self.page_param, [i])
                ele = '<li><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
            page_str_list.append(ele)

        # 下一页
        if self.page == self.total_page_count:
            self.query_dict.setlist(self.page_param, [self.total_page_count])
            next = '<li><a href="?{}" aria-label="Next"><span aria-hidden="true">下一页</span></a></li>'.format(self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [self.page + 1])
            next = '<li><a href="?{}" aria-label="Next"><span aria-hidden="true">下一页</span></a></li>'.format(self.query_dict.urlencode())
        page_str_list.append(next)

        # 跳到尾页
        # self.end_page = '?page={}'.format(self.total_page_count)
        if self.total_page_count == 0:
            self.query_dict.setlist(self.page_param, [1])
            self.end_page = '<li><a href="?{}" aria-label="Next"><span aria-hidden="true">尾页</span></a></li>'.format(self.query_dict.urlencode())
        else:
            self.query_dict.setlist(self.page_param, [self.total_page_count])
            self.end_page = '<li><a href="?{}" aria-label="Next"><span aria-hidden="true">尾页</span></a></li>'.format(self.query_dict.urlencode())
        page_str_list.append(self.end_page)

        self.page_string = mark_safe("".join(page_str_list))
        # print(self.page_string)

        # return self.page_string, self.head_page, self.end_page
        return self.page_string

Django+前端\django\myweb\blog\views\order.py 引用分页组件

from django.shortcuts import render, redirect
from blog.models import Order
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
from blog.utils.form import OrderModelForm
from django.views.decorators.csrf import csrf_exempt
from datetime import datetime
import random
from blog.utils.pagination import Pagination

# 订单展示
def order_list(request):
    form = OrderModelForm()

    data_dict = {}
    search_data = request.GET.get('oid', "")   # 有值拿值,没值为空
    if search_data:
        data_dict["oid__contains"] = search_data

    queryset = Order.objects.filter(**data_dict).order_by("-id")  # 倒序

    page_obj = Pagination(request, queryset)

    context = {
        "order_list": page_obj.page_queryset,
        "search_data": search_data,
        "page_string": page_obj.html(),
        "form": form
    }

    return render(request, 'order_list.html', context)

# 新建订单
@csrf_exempt
def order_add(request):
    """新建订单Ajax请求"""
    form = OrderModelForm(data=request.POST)
    if form.is_valid():
        # print(form.cleaned_data)  # {'title': 'test', 'price': 123, 'status': 1}
        # oid
        # print(datetime.now().strftime("%Y%m%d%H%M%S") + str(random.randint(1000,9999)))
        form.instance.oid = datetime.now().strftime("%Y%m%d%H%M%S") + str(random.randint(1000,9999))
        # admin_username 自定义了db_column 但 ModelForm中原始字段名称仍为 admin_user_id
        # print(request.session.items())   # dict_items([('_session_expiry', 604800), ('info', {'id': 1, 'name': 'tang'})])
        # form.instance.admin_username = request.session["info"]["name"]  # 程序不会报错但无法插入成功

        form.instance.admin_user_id = request.session["info"]["name"]   # 需使用原始字段
        # print(form.instance.admin_user_id)
        form.save()
        data_dict = {"status": True}
        return JsonResponse(data_dict)

    data_dict = {"status": False, 'error': form.errors}
    return JsonResponse(data_dict)

# 删除订单
def order_del(request):
    del_id = request.GET.get("del_id")
    # print(del_id)
    if Order.objects.filter(id=del_id).exists():
        Order.objects.filter(id=del_id).delete()
        return JsonResponse({"status": True})

    data_dict = {"status": False, "error": "删除失败,数据不存在!"}
    return JsonResponse(data_dict)

# 编辑订单显示
def order_detail(request):
    """方式1"""
    # e_id = request.GET.get("e_id")
    # row_object = Order.objects.filter(id=e_id).first()
    # if not row_object:
    #     return JsonResponse({"status": False, "error": "删除失败,数据不存在!"})

    # result = {
    #     "status": True,
    #     "data": {
    #         "title": row_object.title,
    #         "price": row_object.price,
    #         "status": row_object.status
    #     }
    # }

    # return JsonResponse(result)

    """方式2"""
    e_id = request.GET.get("e_id")

    # queryset = Order.objects.all()   # querset对象 queryset = [obj,obj,obj,obj]
    # row_object = Order.objects.filter(id=e_id).first()  # 对象,查询到的当前行所有数据,row_object.id row_object.title row_object.price
    # queryset = Order.objects.filter(id=e_id).values("title","price","status")   # queryset = [{"id": 1, "title": "xxxx"...},{"id": 2, "title": "xxxx"...}]
    # queryset = Order.objects.filter(id=e_id).values_list("title","price","status")  # queryset = [(1,"xxx"...),(2,"xxx"...)...]
    row_dict = Order.objects.filter(id=e_id).values("title","price","status").first()   # 字典 {"id": 1, "title": "xxxx", ...}

    if not row_dict:
        return JsonResponse({"status": False, "error": "数据不存在!"})

    print(row_dict)
    result = {
        "status": True,
        "data": row_dict
    }

    return JsonResponse(result)

# 编辑订单 提交数据
@csrf_exempt
def order_edit(request):
    e_id = request.GET.get("e_id")

    row_object = Order.objects.filter(id=e_id).first()

    if not row_object:
        return JsonResponse({"status": False, "tips": "数据不存在!"})

    form = OrderModelForm(data=request.POST, instance=row_object)

    if form.is_valid():
        form.save()
        return JsonResponse({"status": True, "error": form.errors})