IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python入门自学进阶-Web框架——20、Django其他相关知识2 -> 正文阅读

[Python知识库]Python入门自学进阶-Web框架——20、Django其他相关知识2

三、缓存

?

缓存是可以在任何地方,如内存、文件、数据库、其他机器的内存等。

Django提供的缓存机制:

1、开发调试(虚拟缓存)
2、内存? (本地内存)
3、文件
4、数据库
5、Memcache缓存(python-memcached模块)? ? (分布式内存)
6、Memcache缓存(pylibmc模块)? ? ? ? ? ? ? ? ? ?(分布式内存)

设置缓存:

缓存系统需要少量的设置。必须知道缓存数据应该放在哪里 —— 是在数据库中,还是在文件系统上,或者直接放在内存中。这是一个重要的决定,会影响你的缓存的性能;有些缓存类型比其他类型快。

缓存设置项位于配置文件的缓存配置中。

在settings.py中增加:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',    # 引擎
        'TIMEOUT': 300,                                              # 缓存超时时间,默认300,None表示永不过期,0表示立即过期
        'OPTIONS': {
            'MAX_ENTRIES': 300,                                      # 最大缓存条数,默认300
            'CULL_FREQUENCY': 3,                                     # 当达到 MAX_ENTRIES 时,被删除的条目的比例。实际比例是 1 / CULL_FREQUENCY
        },
        'KEY_PREFIX': '',                                            # 缓存key的前缀(默认空
        'VERSION': 1,                                                # 缓存key的版本,默认1
        'KEY_FUNCTION': hanshu_函数名,                                # 生成key的函数,默认函数会生成:【前缀:版本:key】
    }
}

上面是开发调试,即虚拟缓存的配置,其他的缓存,主要是BACKEND的不同:

'django.core.cache.backends.db.DatabaseCache'
'django.core.cache.backends.dummy.DummyCache'
'django.core.cache.backends.filebased.FileBasedCache'
'django.core.cache.backends.locmem.LocMemCache'
'django.core.cache.backends.memcached.PyMemcacheCache'
'django.core.cache.backends.memcached.PyLibMCCache'

另外还有一个重要的配置项是LOCATION,指定缓存的位置。

对于内存缓存,'django.core.cache.backends.locmem.LocMemCache',其LOCATION指定缓存的名字,相当于一个变量名,内存缓存就是内存中的一块区域,可以看成是一个字典,这里的LOCATION就是这个字典的名字,‘LOCATION’:‘unique-snowflake’,

对于文件缓存,'django.core.cache.backends.filebased.FileBasedCache',其LOCATION指定缓存的文件夹位置,如'LOCATION': '/var/tmp/django_cache',

对于数据库缓存,'django.core.cache.backends.db.DatabaseCache',其LOCATION指定缓存的数据库表名,如‘LOCATION’:‘my_cache_table’,需要执行创建表命令:python manage.py createcachetable

对于Memcache——python-memcached,'django.core.cache.backends.memcached.PyMemcacheCache',其LOCATION指定另外一台机器:

1)‘LOCATION’:‘127.0.0.1:11211’,? 以IP和端口方式连接

2)‘LOCATION’:‘unix:/tmp/memcached.sock’,以socket方式连接,一个文件,文件中写了连接信息,只能连本机。

3)'LOCATION':['172.1.1.1:12211','172.1.1.2:12211',],一个列表指定多台机器,就是集群了,还可以列表中是元组项,指定权重:
'LOCATION':[('172.1.1.1:12211',10),('172.1.1.2:12211',20),],

对于'django.core.cache.backends.memcached.PyLibMCCache'同上面。

应用:主要有全站使用、单独视图缓存、局部视图使用

1、单独视图缓存

首先配置settings,然后使用装饰器cache_page:

# settings中的配置
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': os.path.join(BASE_DIR,'cache'),
    }
}

单独的视图函数使用装饰器来使用缓存:

# 后台视图函数,引入装饰器,对单独函数使用缓存
from django.views.decorators.cache import cache_page
@cache_page(20)    # 参数代表超时时间,单位是秒
def cache(req):
    import time
    v = time.time()
    print(v)
    return HttpResponse(v)

运行后,在文件夹中出现内容了:

?看运行结果:

?第一次请求时,视图函数运行打印了时间,后来的请求都没有运行,20秒后,缓存过期,函数又运行了,打印。

2、局部缓存使用,(前端页面的部分缓存)

使用在模板上,在模板中,先引入模板标签,即引入TemplateTag:{% load cache %}

然后使用缓存:{% cache 10 缓存key %} 缓存内容 {% endcache %}

视图函数:

def part(req):
    import time
    v = time.time()
    print(v)
    return render(req,'part.html',{'v':v})

前端模板:

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{ v }}</h1>
    {% cache 20 key-11 %}
    <h3>{{ v }}</h3>
    {% endcache %}
</body>
</html>

这里会缓存<h3>的内容,在缓存中,其键的值会是“:1:key-11”。

访问时:在缓存时间内,H1数据一直变化,H3是不变的,这个数据从缓存中来。

?后台的打印结果:

每次请求都打印,即都执行了函数,说明函数没有缓存。?

3、全站使用,(要使用中间件)

一般使用两个中间件,一个放在中间件链的开始,一个放在最后,放在最后的中间件,执行process_request,放在第一个的中间件,执行process_response。

这样放的理由:一个请求的到来,是需要经过所有process_request的,相当于过安检,安检过后,才能判断是否在缓存中,也就是在执行视图函数前判断缓存,如果不放在最后一个,有可能安检不通过也能获取数据了,这是放在最后中间件的原因,这个中间件是取缓存的功能,还要有一个中间件放在第一位置,主要执行数据的缓存功能,是执行process_response,这是因为对于返回的内容,其他中间件有可能会进行修改,如果不是第一个,就不是最后执行process_response的中间件,所缓存的内容可能不是最终的内容。(一定要与前面中间件的执行顺序相结合进行理解)。

这两个中间件一个是'django.middleware.cache.UpdateCacheMiddleware'——更新缓存内容,实现内容的缓存和'django.middleware.cache.FetchFromCacheMiddleware'——从缓存中获取内容。

配置如下:

MIDDLEWARE = [
????????'django.middleware.cache.UpdateCacheMiddleware',
? ? ? ? # 其他中间件。。。
????????'django.middleware.cache.FetchFromCacheMiddleware',
]

这样配置后,全站缓存就启用了。

这时再访问前面的part页面时,H1和H3的内容都不变了,都进行了缓存。

?四、信号(Django预留的钩子)

Django有一个“信号调度器(signal dispatcher)”,用来帮助解耦的应用获知框架内任何其他地方发生了操作。简单地说,信号允许某些?发送器?去通知一组?接收器?某些操作发生了。当许多代码段都可能对同一事件感兴趣时,信号特别有用。

内置信号集 使用户代码能够获得 Django 自身某些操作的通知

内置信号:

Model signals
? ? pre_init ? ? ? ? ? ? ? ??# django的model执行其构造方法前,自动触发
? ? post_init ? ? ? ? ? ? ??# django的model执行其构造方法后,自动触发
? ? pre_save ? ? ? ? ? ? # django的model对象保存前,自动触发
? ? post_save ? ? ? ? ? ?# django的model对象保存后,自动触发
? ? pre_delete ? ? ? ? ? ?# django的model对象删除前,自动触发
? ? post_delete ? ? ? ? ?# django的model对象删除后,自动触发
? ? m2m_changed ? ??# django的model中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
? ? class_prepared ? ? ?# 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals
? ? pre_migrate ? ? ? ? ? ? ? ? # 执行migrate命令前,自动触发
? ? post_migrate ? ? ? ? ? ? ? ?# 执行migrate命令后,自动触发
Request/response signals
? ? request_started ? ? ? ? ? ? # 请求到来前,自动触发
? ? request_finished ? ? ? ? ? ?# 请求结束后,自动触发
? ? got_request_exception ? ? ? # 请求异常后,自动触发
Test signals
? ? setting_changed ? ? ? ? ? ? # 使用test测试修改配置文件时,自动触发
? ? template_rendered ? ? ? ? ? # 使用test测试渲染模板时,自动触发
Database Wrappers
? ? connection_created ? ? ? ? ?# 创建数据库连接时,自动触发

对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:

from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception

from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate

from django.test.signals import setting_changed
from django.test.signals import template_rendered

from django.db.backends.signals import connection_created


def callback(sender, **kwargs):
? ? print("xxoo_callback")
? ? print(sender,kwargs)

xxoo.connect(callback)
# xxoo指上述导入的内容,即pre_init、post_init等,如pre_init.connect(callback)

注册的时机,因为是要对所有的一类操作进行信号处理,所有要程序一运行就要注册上去。所以一般写在应用的__init__.py中。

启动项目,会打印:

xxoo_callback
<class 'django.db.backends.sqlite3.base.DatabaseWrapper'> {'signal': <django.dispatch.dispatcher.Signal object at 0x000000000B796160>, 'connection': <django.db.backends.sqlite3.base.DatabaseWrapper object at 0x000000000AD99C50>}?

测试model的信号pre_init和post_init:

创建models类:

from django.db import models

# Create your models here.
from  django.db import models

class User(models.Model):
    username = models.CharField(max_length=32)
    pwd = models.CharField(max_length=32)

注册信号:

from django.db.backends.signals import connection_created
from django.core.signals import request_finished
from django.core.signals import request_started
from django.core.signals import got_request_exception

from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate

from django.test.signals import setting_changed
from django.test.signals import template_rendered

def callback(sender,**kwargs):
    print("xxoo_callback")
    print(sender,"-----",kwargs)

def callback2(sender,**kwargs):
    print("xxoo_callback2")
    print(sender,"-----",kwargs)

connection_created.connect(callback)
pre_init.connect(callback)
post_init.connect(callback2)

视图函数:

def signal(req):
    from midwares import models
    oo = models.User(username='root',pwd='123')
    return HttpResponse('ok')

urls中增加 : path('signal/',views.signal),

前端访问signal:打印结果

xxoo_callback
<class 'midwares.models.User'> ----- {'signal': <django.db.models.signals.ModelSignal object at 0x000000000AFF3198>, 'args': (), 'kwargs': {'username': 'root', 'pwd': '123'}}
xxoo_callback2
<class 'midwares.models.User'> ----- {'signal': <django.db.models.signals.ModelSignal object at 0x000000000AFF34A8>, 'instance': <User: User object (None)>}

对于callback,是pre_init信息注册的,在实例化前执行,sender是<class 'midwares.models.User'>,说明是User类触发的信号,参数中args是位置参数,这里没有传递位置参数,kwargs是我们创建User类对象时传递的参数,username=root,pwd=123,这些就可以在实例化前进行记录。

对于callback2,是实例化后执行的,参数instance是实例化后的对象

以上是Django定义的内置信号,下面我们自定义自己的信号:

1)定义信号:
import django.dispatch
pizza_done = django.dispatch.Singnal(providing_args=["toppings","size"])

def mysignal(req):
    from midwares import pizza_done   # 从应用的__init__.py模块中引入,只需写应用的名,不必加__init__
    pizza_done.send(sender='调用者',toppings='123',size='456') # 自定义的信号,需要自己主动触发,触发就是调用send方法
    return HttpResponse('ok')

2)注册信号:
def callback(sender,**kwargs):
? ? ? ? print("callback")
? ? ? ? print(sender,kwargs)

pizza_done.connect(callback)

3)触发信号:
from 路径 import pizza_done
pizza_done.send(sender='seven',toppings=123,size=456)

示例测试:

在__init__.py中定义信号和注册信号:

# 以下是定义信号
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=['toppings','size'])
# 定义回调函数,注册信号
def callback3(sender,**kwargs):
    print("自定义信号callback3")
    print(sender,kwargs)

pizza_done.connect(callback3)

触发信号:在视图函数中需要自己触发

def mysignal(req):
    from midwares import pizza_done   # 从应用的__init__.py模块中引入,只需写应用的名,不必加__init__
    pizza_done.send(sender='调用者',toppings='123',size='456') # 自定义的信号,需要自己主动触发,触发就是调用send方法
    return HttpResponse('ok')

运行结果:

自定义信号callback3
调用者 {'signal': <django.dispatch.dispatcher.Signal object at 0x000000000B786198>, 'toppings': '123', 'size': '456'}

应用场景:预留插拔接口,如某操作后,需要发送提醒,一开始是短信,后来增加邮件,在增加微信、QQ等,这时使用信号,只要增加callback函数,注册信号就行。

五、BootStrap,集成了css、js一个文件夹? ---? ?响应式+模板

css:在前端网页中引入相应的css,在head中:<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css" >

响应式:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap-5.1.3-dist/css/bootstrap.css">
    <style>
        .pg-header{
            height: 48px;
            background-color: black;
        }
        @media (max-width: 700px) {
            .extra{
                background-color: yellow;
            }
        }
    </style>
</head>
<body>
    <div class="pg-header extra"></div>
</body>
</html>

?

?上面的页面,随着浏览器窗口宽度的变化,在700px以上,div的背景是黑色,缩小的700px以下时,背景变为黄色。这就是响应式。主要是使用@media,bootstrap中的container就是响应式容器

bootstrap中提供了栅格的样式:col-sm-xx,col-md-xx

js:需要先引入jQuery,然后引入bootstrap.js

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:40:12  更:2022-08-06 10:44:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 10:36:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码