zoukankan      html  css  js  c++  java
  • 分页组件与CBV

    一. 自定义分页

    1.准备工作

    (1).首先在models.py中创建一张book表用来存储数据

    1 from django.db import models
    2 class Book(models.Model):
    3     title=models.CharField(max_length=32)
    4     price=models.CharField(max_length=32)
    5     def __str__(self):
    6         return self.title

    (2)index.html中创建大量数据

     1 for j in range(100):
     2     result=""
     3     for i in range(6):
     4         up=chr(random.randint(65,90))
     5         low=chr(random.randint(97,122))
     6         num=str(random.randint(0,9))
     7         choice=random.choice([up,low,num])
     8         result=choice+result
     9     Book.objects.create(title=result,price=j*j)
    10 return HttpResponse("ok")

    2.urls.py中添加一个路径

    1 urlpatterns = [
    2     path('admin/', admin.site.urls),
    3     path('index/', views.index),
    4 ]

    3.视图函数index的准备工作:在一个新的脚本中编写Pagination类

     1 class Pagination():
     2     def __init__(self, current_page_num, all_count, request, per_page_num=5, pager_count=11):
     3         """
     4         封装分页相关数据
     5         :param current_page_num: 当前访问页的数字
     6         :param all_count:    分页数据中的数据总条数
     7         :param per_page_num: 每页显示的数据条数
     8         :param pager_count:  最多显示的页码个数
     9         """
    10         try:
    11             current_page_num = int(current_page_num)
    12         except Exception as e:
    13             current_page_num = 1
    14         if current_page_num < 1:
    15             current_page_num = 1
    16         self.current_page_num = current_page_num
    17         self.all_count = all_count
    18         self.per_page_num = per_page_num
    19         all_pager, tmp = divmod(all_count, per_page_num)
    20         if tmp:
    21             all_pager += 1
    22         self.all_pager = all_pager
    23         self.pager_count = pager_count
    24         self.page_count_half = int((pager_count - 1) / 2)
    25         import copy
    26         self.params = copy.deepcopy(request.GET)
    27 
    28     @property
    29     def start(self):
    30         return int((self.current_page_num - 1) * self.per_page_num)
    31 
    32     @property
    33 
    34     def end(self):
    35         return int(self.current_page_num * self.per_page_num)
    36 
    37     def page_html(self):
    38         if self.all_pager<=self.pager_count:
    39             page_start=1
    40             page_end=self.all_pager+1
    41         else:
    42             if self.current_page_num<=self.page_count_half:
    43                 page_start=1
    44                 page_end=self.pager_count+1
    45             else:
    46                 if self.current_page_num >(self.all_pager-self.page_count_half):
    47                     page_start=self.all_pager-self.pager_count+1
    48                     page_end=self.all_pager+1
    49                 else:
    50                     page_start=self.current_page_num-self.page_count_half
    51                     page_end=self.current_page_num+self.page_count_half+1
    52         page_html_list=[]
    53         first_page='<li><a href="?page=%s">首页</li>' % 1
    54         page_html_list.append(first_page)
    55         if self.current_page_num<=1:
    56             prev_page="<li class='disabled'><a href='#'>上一页</a></li>"
    57         else:
    58             prev_page = "<li ><a href='?page=%s'>上一页</a></li>" % (self.current_page_num-1)
    59         page_html_list.append(prev_page)
    60         for i in range(page_start,page_end):
    61             self.params["page"]=i
    62             if i==self.current_page_num:
    63                 temp="<li class='active'><a href='?%s'>%s</a></li>" % (self.params.urlencode(),i)
    64             else:
    65                 temp = "<li><a href='?%s'>%s</a></li>" % (self.params.urlencode(), i)
    66             page_html_list.append(temp)
    67         if self.current_page_num>=self.all_pager:
    68             next_page="<li class='disabled'><a href='#'>下一页</a></li>"
    69         else:
    70             next_page = "<li ><a href='?page=%s'>下一页</a></li>" % (self.current_page_num+1)
    71         page_html_list.append(next_page)
    72         last_page = '<li><a href="?page=%s">尾页</li>' % (self.all_pager)
    73         page_html_list.append(last_page)
    74         return "".join(page_html_list)

    4.index视图函数

    1 from django.shortcuts import render
    2 from app01.models import Book
    3 def index(request):
    4     from app01.page import Pagination
    5     current_page_num = request.GET.get("page")
    6     book_list = Book.objects.all()
    7     pagination=Pagination(current_page_num,book_list.count(),request)
    8     booklist=book_list[pagination.start:pagination.end]
    9     return render(request,"index.html",locals())

    5.index.html页面

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
     7 
     8 </head>
     9 <body>
    10 <ul>
    11     {% for book in booklist %}
    12     <li>名称:{{ book.title }} 价格:{{ book.price }}</li>
    13     {% endfor %}
    14 <nav aria-label="Page navigation">
    15   <ul class="pagination">
    16    {{ pagination.page_html|safe }}
    17   </ul>
    18 </nav>
    19 </ul>
    20 </body>
    21 </html>

    .保存搜索条件

    1.原码部分:

    为什么request.get得到的queryset不能更改,但是copy之后的queryset可以更改

     1 class QueryDict(MultiValueDict):
     2 
     3 _mutable = True
     4 
     5 #mutable是可更改的意思,默认为true,可以更改
     6 _encoding = None
     7 def __init__(self, query_string=None, mutable=False, encoding=None):
     8 
     9 Pass#当实例化方法执行之后mutable更改为False,不可以更改
    10 
    11    def __copy__(self):
    12        result = self.__class__('', mutable=True, encoding=self.encoding)
    13        for key, value in self.lists():
    14           result.setlist(key, value)
    15        return result
    16     def __deepcopy__(self, memo):
    17        result = self.__class__('', mutable=True, encoding=self.encoding)
    18        memo[id(self)] = result
    19        for key, value in self.lists():
    20            result.setlist(copy.deepcopy(key, memo), copy.deepcopy(value, memo))
    21        return result
    22 
    23 #当执行深拷贝或浅拷贝方法时,mutable又被更改为true,可以更改

    2.urlencode()方法

      拷贝之后可以使用urlencode方法

      params=copy.deepcopy(request.GET)

      print(params.urlencode())

      得到的是搜索条件没有拆包urlencode模式: page=10&a=1

    3.保存搜索条件的方法

    (1)调用该类时,request传进去

    pagination=Pagination(current_page_num,book_list.count(),request)

    (2)在实例化时深拷贝request.GET

    import copy
    self.params = copy.deepcopy(request.GET)

    (3)将搜索条件全都放到parmas字典中,利用urlencode方法,拼接成路径的urlencode模式,并放到相应的位置

    1 for i in range(page_start,page_end):
    2     self.params["page"]=i
    3     if i==self.current_page_num:
    4         temp="<li class='active'><a href='?%s'>%s</a></li>" % (self.params.urlencode(),i)
    5     else:
    6         temp = "<li><a href='?%s'>%s</a></li>" % (self.params.urlencode(), i)
    7     page_html_list.append(temp)

    .CBV

    FBV:function based view,基于函数的视图

    CBV:class based view,基于类的视图

    1.cbv流程

    (1)在视图类创建视图类

     1 from django.shortcuts import render,HttpResponse
     2 from django.views import View
     3 class LoginView(View):
     4     def get(self,request):
     5         return render(request,"login.html")
     6     def post(self,request):
     7         print("post")
     8         return HttpResponse("ok")
     9     def delete(self,request):
    10         pass
    11     def put(self,request):
    12         pass

    (2) urls.py中为该类创建相应的分支

    path('login/', views.LoginView.as_view()),

    (3)创建视图类中需要的HTML

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6 </head>
     7 <body>
     8 <form action="" method="post">
     9     {% csrf_token %}
    10     用户名: <input type="text" name="user">
    11     密码: <input type="text" name="pwd">
    12     <input type="submit">
    13 </form>
    14 </body>
    15 </html>2.原码部分

    2.原码部分

    (1)View中的as_view

     1 @classonlymethod
     2 
     3 def as_view(cls, **initkwargs):
     4 
     5 #cls代表当前类
     6     for key in initkwargs:
     7         if key in cls.http_method_names:
     8             raise TypeError("You tried to pass in the %s method name as a "
     9                             "keyword argument to %s(). Don't do that."
    10                             % (key, cls.__name__))
    11         if not hasattr(cls, key):
    12             raise TypeError("%s() received an invalid keyword %r. as_view "
    13                             "only accepts arguments that are already "
    14                             "attributes of the class." % (cls.__name__, key))
    15 
    16     def view(request, *args, **kwargs):
    17         self = cls(**initkwargs)
    18 
    19 #self代表LoginView的实例对象
    20         if hasattr(self, 'get') and not hasattr(self, 'head'):
    21             self.head = self.get
    22         self.request = request
    23         self.args = args
    24         self.kwargs = kwargs
    25         return self.dispatch(request, *args, **kwargs)
    26 
    27 #分发方法
    28     view.view_class = cls
    29     view.view_initkwargs = initkwargs
    30 
    31     update_wrapper(view, cls, updated=())
    32 
    33     update_wrapper(view, cls.dispatch, assigned=())
    34     return view

    (3) dispatch()

     1 def dispatch(self, request, *args, **kwargs):
     2     if request.method.lower() in self.http_method_names:
     3 
     4 #判断request.mothod是否在self.http_method_names中
     5 
     6 #http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
     7 
     8 #http协议中主要支持的请求方式
     9         handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    10 
    11 #利用反射去LoginView中找其中的某个方法(get)
    12     else:
    13         handler = self.http_method_not_allowed
    14     return handler(request, *args, **kwargs)
    15 
    16 #执行了找到的那个方法(get)

     

     

  • 相关阅读:
    如何使用观测者模式实现监控和推送
    oracle在desc表时,name 和type列不能格式化问题(占位过长)
    [置顶] Vim用正则表达式进行批量修改
    Eclipse扩展点
    写给C语言新手的话
    QQ圈子降级为“应用”后应关注其隐私设置
    win8vs2012创建自带sqlServer数据库出错
    JQuery 选择器
    SINGLETON(单例模式)---(孤独的人)
    C++中的常对象和常对象成员
  • 原文地址:https://www.cnblogs.com/shanghongyun/p/9918183.html
Copyright © 2011-2022 走看看