分页组件与CBV
一. 自定义分页
1.准备工作
(1).首先在models.py中创建一张book表用来存储数据
from django.db import models
class Book(models.Model):
title=models.CharField(max_length=32)
price=models.CharField(max_length=32)
def __str__(self):
return self.title
(2)在index.html中创建大量数据
for j in range(100):
result=""
for i in range(6):
up=chr(random.randint(65,90))
low=chr(random.randint(97,122))
num=str(random.randint(0,9))
choice=random.choice([up,low,num])
result=choice+result
Book.objects.create(title=result,price=j*j)
return HttpResponse("ok")
2.在urls.py中添加一个路径
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
]
3.视图函数index的准备工作:在一个新的脚本中编写Pagination类
class Pagination():
def __init__(self, current_page_num, all_count, request, per_page_num=5, pager_count=11):
"""
封装分页相关数据
:param current_page_num: 当前访问页的数字
:param all_count: 分页数据中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
"""
try:
current_page_num = int(current_page_num)
except Exception as e:
current_page_num = 1
if current_page_num < 1:
current_page_num = 1
self.current_page_num = current_page_num
self.all_count = all_count
self.per_page_num = per_page_num
all_pager, tmp = divmod(all_count, per_page_num)
if tmp:
all_pager += 1
self.all_pager = all_pager
self.pager_count = pager_count
self.page_count_half = int((pager_count - 1) / 2)
import copy
self.params = copy.deepcopy(request.GET) @property
def start(self):
return int((self.current_page_num - 1) * self.per_page_num) @property def end(self):
return int(self.current_page_num * self.per_page_num) def page_html(self):
if self.all_pager<=self.pager_count:
page_start=1
page_end=self.all_pager+1
else:
if self.current_page_num<=self.page_count_half:
page_start=1
page_end=self.pager_count+1
else:
if self.current_page_num >(self.all_pager-self.page_count_half):
page_start=self.all_pager-self.pager_count+1
page_end=self.all_pager+1
else:
page_start=self.current_page_num-self.page_count_half
page_end=self.current_page_num+self.page_count_half+1
page_html_list=[]
first_page='<li><a href="?page=%s">首页</li>' % 1
page_html_list.append(first_page)
if self.current_page_num<=1:
prev_page="<li class='disabled'><a href='#'>上一页</a></li>"
else:
prev_page = "<li ><a href='?page=%s'>上一页</a></li>" % (self.current_page_num-1)
page_html_list.append(prev_page)
for i in range(page_start,page_end):
self.params["page"]=i
if i==self.current_page_num:
temp="<li class='active'><a href='?%s'>%s</a></li>" % (self.params.urlencode(),i)
else:
temp = "<li><a href='?%s'>%s</a></li>" % (self.params.urlencode(), i)
page_html_list.append(temp)
if self.current_page_num>=self.all_pager:
next_page="<li class='disabled'><a href='#'>下一页</a></li>"
else:
next_page = "<li ><a href='?page=%s'>下一页</a></li>" % (self.current_page_num+1)
page_html_list.append(next_page)
last_page = '<li><a href="?page=%s">尾页</li>' % (self.all_pager)
page_html_list.append(last_page)
return "".join(page_html_list)
4.index视图函数
from django.shortcuts import render
from app01.models import Book
def index(request):
from app01.page import Pagination
current_page_num = request.GET.get("page")
book_list = Book.objects.all()
pagination=Pagination(current_page_num,book_list.count(),request)
booklist=book_list[pagination.start:pagination.end]
return render(request,"index.html",locals())
5.index.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<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"> </head>
<body>
<ul>
{% for book in booklist %}
<li>名称:{{ book.title }} 价格:{{ book.price }}</li>
{% endfor %}
<nav aria-label="Page navigation">
<ul class="pagination">
{{ pagination.page_html|safe }}
</ul>
</nav>
</ul>
</body>
</html>
二.保存搜索条件
1.原码部分:
为什么request.get得到的queryset不能更改,但是copy之后的queryset可以更改
class QueryDict(MultiValueDict): _mutable = True #mutable是可更改的意思,默认为true,可以更改
_encoding = None
def __init__(self, query_string=None, mutable=False, encoding=None): Pass#当实例化方法执行之后mutable更改为False,不可以更改 def __copy__(self):
result = self.__class__('', mutable=True, encoding=self.encoding)
for key, value in self.lists():
result.setlist(key, value)
return result
def __deepcopy__(self, memo):
result = self.__class__('', mutable=True, encoding=self.encoding)
memo[id(self)] = result
for key, value in self.lists():
result.setlist(copy.deepcopy(key, memo), copy.deepcopy(value, memo))
return result #当执行深拷贝或浅拷贝方法时,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模式,并放到相应的位置
for i in range(page_start,page_end):
self.params["page"]=i
if i==self.current_page_num:
temp="<li class='active'><a href='?%s'>%s</a></li>" % (self.params.urlencode(),i)
else:
temp = "<li><a href='?%s'>%s</a></li>" % (self.params.urlencode(), i)
page_html_list.append(temp)
三.CBV
FBV:function based view,基于函数的视图
CBV:class based view,基于类的视图
1.cbv流程
(1)在视图类创建视图类
from django.shortcuts import render,HttpResponse
from django.views import View
class LoginView(View):
def get(self,request):
return render(request,"login.html")
def post(self,request):
print("post")
return HttpResponse("ok")
def delete(self,request):
pass
def put(self,request):
pass
(2) 在urls.py中为该类创建相应的分支
path('login/', views.LoginView.as_view()),
(3)创建视图类中需要的HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
用户名: <input type="text" name="user">
密码: <input type="text" name="pwd">
<input type="submit">
</form>
</body>
</html>2.原码部分
2.原码部分
(1)View中的as_view
@classonlymethod def as_view(cls, **initkwargs): #cls代表当前类
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key)) def view(request, *args, **kwargs):
self = cls(**initkwargs) #self代表LoginView的实例对象
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs) #分发方法
view.view_class = cls
view.view_initkwargs = initkwargs update_wrapper(view, cls, updated=()) update_wrapper(view, cls.dispatch, assigned=())
return view
(3) dispatch()
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names: #判断request.mothod是否在self.http_method_names中 #http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] #http协议中主要支持的请求方式
handler = getattr(self, request.method.lower(), self.http_method_not_allowed) #利用反射去LoginView中找其中的某个方法(get)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) #执行了找到的那个方法(get)
分页组件与CBV的更多相关文章
- 基于Vue.js的表格分页组件
有一段时间没更新文章了,主要是因为自己一直在忙着学习新的东西而忘记分享了,实在惭愧. 这不,大半夜发文更一篇文章,分享一个自己编写的一个Vue的小组件,名叫BootPage. 不了解Vue.js的童鞋 ...
- angular-ui分页组件
http://angular-ui.github.io/bootstrap/#/pagination 分页组件只提供生成分页按钮,数据的显示需要使用ng-repeat, 注意设置 items-per- ...
- asp.net mvc4+mysql做一个简单分页组件(部分视图)
在开始做mysql分页功能组件前,便设定的是要有一定可复用性.先在项目里Views文件夹下右键新建名为_PaginationComponent.cshtml,这里html及css我采用的bootstr ...
- ReactJS实现的通用分页组件
大家多少都自己写过各种版本的分页工具条吧,像纯服务版的,纯jsWeb板的,Angular版的,因为这个基础得不能再基础的功能太多地方都会用到,下面我给出以个用ReactJS实现的版本,首先上图看下效果 ...
- 基于vue2.0的分页组件开发
今天安排的任务是写基于vue2.0的分页组件,好吧,我一开始是觉得超级简单的,但是越写越写不出来,写的最后乱七八糟的都不知道下句该写什么了,所以重新捋了思路,小结一下- 首先写组件需要考虑: 要从父组 ...
- 基于Vue封装分页组件
使用Vue做双向绑定的时候,可能经常会用到分页功能 接下来我们来封装一个分页组件 先定义样式文件 pagination.css ul, li { margin: 0px; padding: 0px;} ...
- [js开源组件开发]ajax分页组件
ajax分页组件 我以平均每一周出一个开源的js组件为目标行动着,虽然每个组件并不是很庞大,它只完成某一个较小部分的工作,但相信,只要有付出,总会得到回报的.这个组件主要完成分页的工作. 这张图里显示 ...
- javascript 分页组件
自己写的一个简单的分页组件,主要功能还有实现都在JS中,html页面中只用增加一个放置生成分页的DIV,并给定容器的id. html结构如下: <ul class="paginatio ...
- 一步步编写avalon组件02:分页组件
本章节,我们做分页组件,这是一个非常常用的组件.grid, listview都离不开它.因此其各种形态也有. 本章节教授的是一个比较纯正的形态,bootstrap风格的那种分页栏. 我们建立一个ms- ...
随机推荐
- CodeBlocks提供了预编译的WxWidgets模块,并预置TDM
Miscellaneous For Windows, we also provide the pre-compiled wxWidgets, version 2.8.12 used to compil ...
- android studio 各种问题 应该能帮助到你们
1. you can import your settings from a previous version of Studio 可以导入您的设置从先前版本的工作室 2. I want to imp ...
- JVM参数调优:Eclipse启动实践
本文主要参考自<深入理解 Java 虚拟机>.这本书是国人写的难得的不是照搬代码注释的且不是废话连篇的技术书,内容涵盖了 Java 从源码到字节码到执行的整个过程,包括了 JVM(Java ...
- Method for training dynamic random access memory (DRAM) controller timing delays
Timing delays in a double data rate (DDR) dynamic random access memory (DRAM) controller (114, 116) ...
- Memory device control for self-refresh mode
To ensure that a memory device operates in self-refresh mode, the memory controller includes (1) a n ...
- Scala-Numbers
Scala之Numbers 一.前言 前面已经学习了Scala中的String,接着学习Scala的Numbers. 二.Numbers 在Scala中,所有的数字类型,如Byte,Char,Doub ...
- LaTex 加粗(加黑)的方式
1. 基本 LaTeX技巧458:关于LaTeX数学字体加粗 $\mathbf $,会变为粗体,但也导致数学字母斜体形式的丢失: 使用 amsmath package 的 \boldmath 命令: ...
- 第一泰泽(Tizen)智能手机发布在俄罗斯
请看下图: 这是韩国三星公司在俄罗斯境内公布的第一款泰泽(Tizen)智能手机(今年6月2日).这说明,Tizen操作系统没有死去. 在泰泽官网上将泰泽操作系统定义为:"The OS of ...
- python下载图片(3)
# -*- coding: utf-8 -*-"""some function by metaphy,2007-04-03,copyleftversion 0.2&quo ...
- Win32 键盘事件 - 击键消息、字符消息、插入符号(光标)
注:以下内容为学习笔记,多数是从书本.资料中得来,只为加深印象,及日后参考.然而本人表达能力较差,写的不好.因非翻译.非转载,只好选原创,但多数乃摘抄,实为惭愧.但若能帮助一二访客,幸甚! 以下内容主 ...