Django 分页器 缓存 信号 序列化
阅读目录
- 分页器
- 缓存
- 信号
- 序列化
Django分页器 (paginator)
导入
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
view
from django.shortcuts import render,HttpResponse from app01.models import * from django.core.paginator import Paginator, EmptyPage, PageNotAnIntegerdef index(request):currentPage = request.GET.get("page",1)currentPage = int(currentPage)book_list = foo.objects.all()paginator = Paginator(book_list, 10) # 每页显示10条数据# print("count:",paginator.count) #数据总数# print("num_pages",paginator.num_pages) #总页数# print("page_range",paginator.page_range) #页码的列表if paginator.num_pages>10:if currentPage-5<1:pageRange=range(1,10)elif currentPage+5>paginator.num_pages:pageRange=range(currentPage-5,paginator.num_pages+1)else:pageRange=range(currentPage-4,currentPage+5)else:pageRange=paginator.page_rangetry:book_list = paginator.page(currentPage) # 第num页的page对象except EmptyPage: # 如果大于总页数book_list = paginator.page(paginator.num_pages)except PageNotAnInteger: # 如果num不是数字book_list = paginator.page(1)# print(book_list.object_list) #第1页的所有数据 QuerySet# print(book_list.has_next()) #是否有下一页# print(book_list.next_page_number()) #下一页的页码# print(book_list.has_previous()) #是否有上一页# print(book_list.previous_page_number()) #上一页的页码# 抛错# page=paginator.page(12) # error:EmptyPage# page=paginator.page("z") # error:PageNotAnIntegerreturn render(request,"inde.html",locals())
模版
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body><div class="container"><h4>分页器</h4><ul>{% for book in book_list %}<li>{{ book.title }} -----{{ book.price }}</li>{% endfor %}</ul><ul class="pagination" id="pager">{% if book_list.has_previous %}<li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li>{% else %}<li class="previous disabled"><a href="#">上一页</a></li>{% endif %}{% for num in pageRange %}{% if num == currentPage %}<li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li>{% else %}<li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li>{% endif %}{% endfor %}{% if book_list.has_next %}<li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li>{% else %}<li class="next disabled"><a href="#">下一页</a></li>{% endif %}</ul> </div></body> </html>
自定义分页器组件
""" 分页组件使用示例:obj = Pagination(request.GET.get('page',1),len(USER_LIST),request.path_info,request.GET)page_user_list = USER_LIST[obj.start:obj.end]page_html = obj.page_html()return render(request,'index.html',{'users':page_user_list,'page_html':page_html})#基于bootstarp样式,需要引入bootstrap的css文件。"""class Pagination(object):def __init__(self,current_page,all_count,base_url,params,per_page_num=10,pager_count=11):"""封装分页相关数据:param current_page: 当前页:param all_count: 数据库中的数据总条数:param per_page_num: 每页显示的数据条数:param base_url: 分页中显示的URL前缀:param pager_count: 最多显示的页码个数"""try:current_page = int(current_page)except Exception as e:current_page = 1if current_page <1:current_page = 1self.current_page = current_pageself.all_count = all_countself.per_page_num = per_page_numself.base_url = base_url# 总页码all_pager, tmp = divmod(all_count, per_page_num)if tmp:all_pager += 1self.all_pager = all_pagerself.pager_count = pager_countself.pager_count_half = int((pager_count - 1) / 2)import copyparams = copy.deepcopy(params)params._mutable = Trueself.params = params@propertydef start(self):return (self.current_page - 1) * self.per_page_num@propertydef end(self):return self.current_page * self.per_page_numdef page_html(self):# 如果总页码 < 11个:if self.all_pager <= self.pager_count:pager_start = 1pager_end = self.all_pager + 1# 总页码 > 11else:# 当前页如果<=页面上最多显示11/2个页码if self.current_page <= self.pager_count_half:pager_start = 1pager_end = self.pager_count + 1# 当前页大于5else:# 页码翻到最后if (self.current_page + self.pager_count_half) > self.all_pager:pager_end = self.all_pager + 1pager_start = self.all_pager - self.pager_count + 1else:pager_start = self.current_page - self.pager_count_halfpager_end = self.current_page + self.pager_count_half + 1page_html_list = []page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')self.params["page"] = 1first_page = '<li><a href="%s?%s">首页</a></li>' % (self.base_url,self.params.urlencode(),)page_html_list.append(first_page)if self.current_page <= 1:prev_page = '<li class="disabled"><a href="#">上一页</a></li>'else:self.params["page"] = self.current_page - 1prev_page = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url,self.params.urlencode(),)page_html_list.append(prev_page)for i in range(pager_start, pager_end):self.params["page"] = iif i == self.current_page:temp = '<li class="active"><a href="%s?%s">%s</a></li>' % (self.base_url,self.params.urlencode(), i,)else:temp = '<li><a href="%s?%s">%s</a></li>' % (self.base_url,self.params.urlencode(), i,)page_html_list.append(temp)if self.current_page >= self.all_pager:next_page = '<li class="disabled"><a href="#">下一页</a></li>'else:self.params["page"] = self.current_page + 1next_page = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url,self.params.urlencode(),)page_html_list.append(next_page)self.params["page"] = self.all_pagerlast_page = '<li><a href="%s?%s">尾页</a></li>' % (self.base_url,self.params.urlencode(),)page_html_list.append(last_page)page_html_list.append('</ul></nav>')return ''.join(page_html_list)
View Code
Django 缓存机制
1.1 缓存介绍
1.缓存的简介
在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面.
当一个网站的用户访问量很大的时候,每一次的的后台操作,都会消耗很多的服务端资源,所以必须使用缓存来减轻后端服务器的压力.
缓存是将一些常用的数据保存内存或者memcache中,在一定的时间内有人来访问这些数据时,则不再去执行数据库及渲染等操作,而是直接从内存或memcache的缓存中去取得数据,然后返回给用户.
2.Django提供了6种huan存方式
- 开发调试缓存
- 内存缓存
- 文件缓存
- 数据库缓存
- Memcache缓存(使用python-memcached模块)
- Memcache缓存(使用pylibmc模块)
经常使用的有文件缓存和Mencache缓存
1.2 各种缓存配置
1.2.1 开发调试(此模式为开发调试使用,实际上不执行任何操作)
settings.py文件配置
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 缓存后台使用的引擎'TIMEOUT': 300, # 缓存超时时间(默认300秒,None表示永不过期,0表示立即过期)'OPTIONS':{'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) },} }
View Code
1.2.2 内存缓存(将缓存内容保存至内存区域中)
settings.py文件配置
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # 指定缓存使用的引擎'LOCATION': 'unique-snowflake', # 写在内存中的变量的唯一值 'TIMEOUT':300, # 缓存超时时间(默认为300秒,None表示永不过期)'OPTIONS':{'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) } } }
View Code
1.2.3 文件缓存(把缓存数据存储在文件中)
settings.py文件配置
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定缓存使用的引擎'LOCATION': '/var/tmp/django_cache', #指定缓存的路径'TIMEOUT':300, #缓存超时时间(默认为300秒,None表示永不过期)'OPTIONS':{'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }} }
View Code
1.2.4 数据库缓存(把缓存数据存储在数据库中)
settings.py文件配置
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.db.DatabaseCache', # 指定缓存使用的引擎'LOCATION': 'cache_table', # 数据库表 'OPTIONS':{'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) } } }
View Code
注意,创建缓存的数据库表使用的语句:
python manage.py createcachetable
1.2.5 Memcache缓存(使用python-memcached模块连接memcache)
Memcached是Django原生支持的缓存系统.要使用Memcached,需要下载Memcached的支持库python-memcached或pylibmc.
settings.py文件配置
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', # 指定缓存使用的引擎'LOCATION': '192.168.10.100:11211', # 指定Memcache缓存服务器的IP地址和端口'OPTIONS':{'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }} }
View Code
LOCATION也可以配置成如下:
'LOCATION': 'unix:/tmp/memcached.sock', # 指定局域网内的主机名加socket套接字为Memcache缓存服务器 'LOCATION': [ # 指定一台或多台其他主机ip地址加端口为Memcache缓存服务器'192.168.10.100:11211','192.168.10.101:11211','192.168.10.102:11211', ]
View Code
1.2.6 Memcache缓存(使用pylibmc模块连接memcache)
settings.py文件配置CACHES = {'default': {'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', # 指定缓存使用的引擎'LOCATION':'192.168.10.100:11211', # 指定本机的11211端口为Memcache缓存服务器'OPTIONS':{'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }, }}
View Code
LOCATION也可以配置成如下:
'LOCATION': '/tmp/memcached.sock', # 指定某个路径为缓存目录 'LOCATION': [ # 分布式缓存,在多台服务器上运行Memcached进程,程序会把多台服务器当作一个单独的缓存,而不会在每台服务器上复制缓存值'192.168.10.100:11211','192.168.10.101:11211','192.168.10.102:11211', ]
View Code
Memcached是基于内存的缓存,数据存储在内存中.所以如果服务器死机的话,数据就会丢失,所以Memcached一般与其他缓存配合使用
1.3 Django中的缓存应用
Django提供了不同粒度的缓存,可以缓存某个页面,可以只缓存一个页面的某个部分,甚至可以缓存整个网站.
对一个视图函数设置缓存
from django.views.decorators.cache import cache_page
import time
from .models import *@cache_page(15) #超时时间为15秒
def index(request):t=time.time() #获取当前时间bookList=Book.objects.all()return render(request,"index.html",locals())
上面的例子是基于内存的缓存配置,基于文件的缓存该怎么配置呢??
更改settings.py的配置
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', # 指定缓存使用的引擎'LOCATION': 'E:\django_cache', # 指定缓存的路径'TIMEOUT': 300, # 缓存超时时间(默认为300秒,None表示永不过期)'OPTIONS': {'MAX_ENTRIES': 300, # 最大缓存记录的数量(默认300)'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3) }} }
View Code
然后再次刷新浏览器,可以看到在刚才配置的目录下生成的缓存文件
通过实验可以知道,Django会以自己的形式把缓存文件保存在配置文件中指定的目录中.
全站使用缓存,配置中间件
既然是全站缓存,当然要使用Django中的中间件.
用户的请求通过中间件,经过一系列的认证等操作,如果请求的内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户
当返回给用户之前,判断缓存中是否已经存在,如果不存在,则UpdateCacheMiddleware会将缓存保存至Django的缓存之中,以实现全站缓存
缓存整个站点,是最简单的缓存方法在 MIDDLEWARE_CLASSES 中加入 “update” 和 “fetch” 中间件
MIDDLEWARE_CLASSES = (‘django.middleware.cache.UpdateCacheMiddleware’, #第一'django.middleware.common.CommonMiddleware',‘django.middleware.cache.FetchFromCacheMiddleware’, #最后
)
“update” 必须配置在第一个
“fetch” 必须配置在最后一个
修改settings.py配置文件
MIDDLEWARE_CLASSES = ('django.middleware.cache.UpdateCacheMiddleware', #响应HttpResponse中设置几个headers'django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.auth.middleware.SessionAuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware','django.middleware.security.SecurityMiddleware','django.middleware.cache.FetchFromCacheMiddleware', #用来缓存通过GET和HEAD方法获取的状态码为200的响应 )CACHE_MIDDLEWARE_SECONDS=10
View Code
模版局部缓存
{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h3 style="color: green">不缓存:-----{{ t }}</h3>{% cache 2 'name' %}<h3>缓存:-----:{{ t }}</h3>
{% endcache %}</body>
</html>
Django 信号
Django提供一种信号机制。其实就是观察者模式,又叫发布-订阅(Publish/Subscribe) 。当发生一些动作的时候,发出信号,然后监听了这个信号的函数就会执行。
通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。用于在框架执行操作时解耦。
2.1、Django内置信号
Model signalspre_init # django的modal执行其构造方法前,自动触发post_init # django的modal执行其构造方法后,自动触发pre_save # django的modal对象保存前,自动触发post_save # django的modal对象保存后,自动触发pre_delete # django的modal对象删除前,自动触发post_delete # django的modal对象删除后,自动触发m2m_changed # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发class_prepared # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signalspre_migrate # 执行migrate命令前,自动触发post_migrate # 执行migrate命令后,自动触发
Request/response signalsrequest_started # 请求到来前,自动触发request_finished # 请求结束后,自动触发got_request_exception # 请求异常后,自动触发
Test signalssetting_changed # 使用test测试修改配置文件时,自动触发template_rendered # 使用test测试渲染模板时,自动触发
Database Wrappersconnection_created # 创建数据库连接时,自动触发
Django 提供了一系列的内建信号,允许用户的代码获得DJango的特定操作的通知。这包含一些有用的通知: django.db.models.signals.pre_save & django.db.models.signals.post_save在模型 save()方法调用之前或之后发送。 django.db.models.signals.pre_delete & django.db.models.signals.post_delete在模型delete()方法或查询集的delete() 方法调用之前或之后发送。 django.db.models.signals.m2m_changed模型上的 ManyToManyField 修改时发送。 django.core.signals.request_started & django.core.signals.request_finishedDjango建立或关闭HTTP 请求时发送。
View Code
对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:
方式1:
from django.core.signals import request_finishedfrom django.core.signals import request_startedfrom django.core.signals import got_request_exceptionfrom django.db.models.signals import class_preparedfrom django.db.models.signals import pre_init, post_initfrom django.db.models.signals import pre_save, post_savefrom django.db.models.signals import pre_delete, post_deletefrom django.db.models.signals import m2m_changedfrom django.db.models.signals import pre_migrate, post_migratefrom django.test.signals import setting_changedfrom django.test.signals import template_renderedfrom django.db.backends.signals import connection_createddef callback(sender, **kwargs):print("pre_save_callback")print(sender,kwargs)pre_save.connect(callback) # 该脚本代码需要写到app或者项目的初始化文件中 init文件,当项目启动时执行注册代码
方式2:
from django.core.signals import request_finished
from django.dispatch import receiver@receiver(request_finished)
def my_callback(sender, **kwargs):print("Request finished!")
2.2、自定义信号
a. 定义信号
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
b. 注册信号
def callback(sender, **kwargs):print("callback")print(sender,kwargs)pizza_done.connect(callback)
c. 触发信号
from 路径 import pizza_donepizza_done.send(sender='seven',toppings=123, size=456)
由于内置信号的触发者已经集成到Django中,所以其会自动调用,而对于自定义信号则需要开发者在任意位置触发。
练习:数据库添加一条记录时生成一个日志记录。
Django 的序列化
关于Django中的序列化主要应用在将数据库中检索的数据返回给客户端用户,特别的Ajax请求一般返回的为Json格式。
1、serializers
from django.core import serializersret = models.BookType.objects.all()data = serializers.serialize("json", ret)
2、json.dumps
import json#ret = models.BookType.objects.all().values('caption')
ret = models.BookType.objects.all().values_list('caption')ret=list(ret)result = json.dumps(ret)
由于json.dumps时无法处理datetime日期,所以可以通过自定义处理器来做扩展,如:
import json from datetime import date from datetime import datetimed=datetime.now()class JsonCustomEncoder(json.JSONEncoder):def default(self, field):if isinstance(field, datetime):return field.strftime('%Y-%m-%d %H:%M---%S')elif isinstance(field, date):return field.strftime('%Y-%m-%d')else:return json.JSONEncoder.default(self, field)ds = json.dumps(d, cls=JsonCustomEncoder)print(ds) print(type(ds))''' Supports the following objects and types by default:+-------------------+---------------+| Python | JSON |+===================+===============+| dict | object |+-------------------+---------------+| list, tuple | array |+-------------------+---------------+| str | string |+-------------------+---------------+| int, float | number |+-------------------+---------------+| True | true |+-------------------+---------------+| False | false |+-------------------+---------------+| None | null |+-------------------+---------------+'''
转载于:https://www.cnblogs.com/zhoujunhao/p/8059497.html
Django 分页器 缓存 信号 序列化相关推荐
- Django 缓存、序列化、信号
一,缓存 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcac ...
- django 不包括字段 序列化器_手写一个Django序列化功能
本文章的代码已上传至github上(github包含了更多功能,相关文章后续更新) AGL1994/django-buildinggithub.com 前言 目前Django比较知名的序列化框架有D ...
- Django 的缓存机制
一 缓存介绍: 在动态网站中,用户所有的请求,服务器都会去数据库中进行相应的增,删,查,改,渲染模板,执行业务逻辑,最后生成用户看到的页面. 当一个网站的用户访问量很大的时候,每一次的的后台操作,都会 ...
- Django使用缓存笔记
2019独角兽企业重金招聘Python工程师标准>>> Django设置缓存需要在settings.py文件中进行设置,缓存配置是通过setting文件的CACHES 配置来实现的. ...
- Django入门(七) django的缓存
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者Redis中,5分钟内 ...
- Django - 分页器
一.分页器: 知识点先览 Paginator:Django分页器bulk_create:批量插入数据paginator.count:数据总数,其中paginator是分页器实例化对象paginator ...
- 关于Django中,实现序列化的几种不同方法
前言 关于序列化操作,就是将一个可迭代的数据结构,通过便利的方式进行我们所需要的操作. 今天历来归纳一下,Django中的几种不同得分方法,已经Django-restframework提供的方法 创建 ...
- Django分页器和自定义分页器
一.自定义分页器 import copyclass Pagination():def __init__(self,request,current_page,all_data_num,each_page ...
- Django(缓存系统)
什么是缓存Cache 缓存是一类可以更快的读取数据的介质统称,也指其它可以加快数据读取的存储方式.一般用来存储临时数据,常用介质的是读取速度很快的内存.一般来说从数据库多次把所需要的数据提取出来,要比 ...
- Django之缓存篇
1.什么是缓存 定义:缓存是一类可以更快的读取数据的介质统称,也指其他可以加快得数据读取的存储方式.一般来存储临时数据,常用的介质是快速很快据的内存. 意义:试图渲染有一定的成本,数据库查询的频率过高 ...
最新文章
- 148. Sort List
- SAP Spartacus layoutSlots ID 和 CMSComponent 的映射关系
- android对skia的封装,Skia引擎API整理介绍(skia in Android 2.3 trunk)
- Graphicsmagick linux 中文水印乱码-new
- php重写curl_setopt函数,PHP curl_share_setopt函数
- [HttpClient]HTTPClient PostMethod 中文乱码问题解决方案(2种)
- 用python语言提取千位数_C语言怎样提取一个数的十位个位百位千位?
- 《用户故事与敏捷方法》 笔记
- 学习OpenCV——计算邻接区域列表(build_adjoin)
- 有意思的网站 - 收集
- 【C++---16】常指针和常引用
- 2021-05-11 MongoDB面试题 MySQL与MongoDB之间最基本的差别是什么
- 算法与数据结构实验题 5.18 小孩的游戏
- Android中画布连线的连线动画的实现
- HighCharts生成柏拉图
- E1协议转换器使用中常见故障问题及处理方法总结
- Linux Polkit权限提升漏洞(CVE-2021-3560)
- HSG1510轻便式移动工作灯
- 映美Jolimark TP108W 打印机驱动
- Vue实现媒体文件下载
热门文章
- 小程序中canvas绘制网络图片
- 小程序之旅——第四站(模板框架)
- 错误 Cannot load driver class: com.mysql.jdbc.Driver
- [译]Quartz.NET 框架 教程(中文版)2.2.x 之第五课 SimpleTrigger
- 关于Eclipse的常用快捷键
- LeetCode 148 排序链表
- day3—python——文件操作
- 移动端下拉刷新,向后台请求数据
- IE6 CSS高度height:100% 无效解决方法总结
- 约瑟夫(环)问题(Josephus problem)