Django13 /缓存、信号、django的读写分离

1. 缓存

  • 缓存简述:

    缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行views中的操作,而是直接从内存或者memcache中之前缓存的内容拿到,并返回。
  • Django中缓存的方式

    开发调试
    内存
    文件
    数据库
    Memcache缓存(python-memcached模块)
    Memcache缓存(pylibmc模块)
  • 各种方式的配置

    1、将缓存内容保存在内存的变量中(django的默认配置)

    # settings配置文件中写如下配置:
    
    CACHES = {
    'default': {
    'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    'LOCATION': 'unique-snowflake', #这是一个唯一标示,写啥都行
    'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
    'OPTIONS':{
    'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
    'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
    },
    } }

    2、将缓存内容保存在文件中

    # settings配置文件中写如下配置:
    
    CACHES = {
    'default': {
    'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
    'LOCATION': '/var/tmp/django_cache', #缓存文件存放路径
    }
    }

    3、将缓存内容保存在数据库中

    # settings配置文件中写如下配置:
    
    # 方式一:执行创建表命令生成数据库表
    CACHES = {
    'default': {
    'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
    'LOCATION': 'my_cache_table', # 数据库表
    }
    } # 注:执行创建表命令 python manage.py createcachetable,数据库中会自动生成名字为my_cache_table的表作为缓存表 # 方式二:自己创建存放缓存内容的数据库表
    from django.db import models class CacheTalbe(models.Model):
    cache_key = models.CharField(max_length=2000)
    value = models.CharField(max_length=2000,null=True)
    expires = models.DateTimeField(null=True) # 注:如果自己手动创建这个缓存表的时候,数据库表的三个字段是必须要有的:看下面的表,并且不需要制定上面的createcachetable指令就可以使用。

    4、将缓存内容保存在redis中

    # settings配置文件中写如下配置:
    
    CACHES = {
    "default": {
    "BACKEND": "django_redis.cache.RedisCache",
    "LOCATION": "redis://127.0.0.1:6379",
    "OPTIONS": {
    "CLIENT_CLASS": "django_redis.client.DefaultClient",
    }
    }
    }
  • 缓存的使用

    1、单独视图使用缓存

    # 方式一:语法糖装饰器
    from django.views.decorators.cache import cache_page
    import time
    @cache_page(5) # 设置5秒后缓存到期
    def my_view(request):
    tm = time.time() # 用时间戳模拟测试
      return render(request,'index.html',{'tm':tm }) # 刷新页面,5s内会一直使用缓存 # 方式二:装饰器原始用法
    from django.views.decorators.cache import cache_page
    urlpatterns = [
    url(r'^foo/([0-9]{1,2})/$', cache_page(5)(my_view)),
    ]

    2、模板局部使用缓存,就不需要在视图中设置缓存了

    <!-- 用法如下: -->
    
    a. 引入TemplateTag
    {% load cache %} b. 使用缓存
    {% cache 5 key %} <!-- key就是存储缓存时的键 -->
    缓存的内容
    {% endcache %}
    <!-- 示例代码如下: -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body> <h1>测试模板局部使用缓存</h1>
    <h2>{{ tm }}</h2> {% load cache %}
    {% cache 5 'key' %}
    <h2>{{ tm }}</h2>
    {% endcache %} </body>
    </html>

    3、全局使用缓存

    # settings配置文件进行如下配置:
    
    MIDDLEWARE = [
    'django.middleware.cache.UpdateCacheMiddleware', # 中间件第一个
    # 其他中间件...
    'django.middleware.cache.FetchFromCacheMiddleware', # 中间件最后一个
    ] CACHE_MIDDLEWARE_ALIAS = "" # 用于存储的缓存别名。
    CACHE_MIDDLEWARE_SECONDS = "" # 缓存的过期秒数
    CACHE_MIDDLEWARE_KEY_PREFIX = "" # 如果使用同一django安装跨多个站点共享缓存,请将其设置为站点名称或此django实例唯一的其他字符串,以防止密钥冲突。如果不在乎,就用空字符串。 # 注意:使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存
  • 总结:

    • 缓存是以加密的形式进行保存的
    • 对实时性数据要求很高的,不要做缓存

2. 信号

  • 信号简述:

    Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。
  • Django内置的信号

    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 # 创建数据库连接时,自动触发
  • 信号的使用

    1、注册指定信号,当程序执行相应操作时,自动触发注册函数

    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): # sender表示信号触发者
    print("已经触发信号了")
    print(sender,kwargs) post_save.connect(callback) # 表示model对象保存后,会自动触发callback函数 # 在视图中或者项目或者应用的__init__.py文件中注册信号

    2、在视图函数中,做相应的操作就会触发相应的函数

    from app01 import models
    
    def func(sender,**kwargs):
    models.Book.objects.create(title='python')
    return HttpReponse('ok')
  • 自定义信号

    1、定义信号:在某py文件或者项目或者应用的__init__.py文件中定义信号。

    import django.dispatch
    pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"]) # 注意:toppings和size这两个参数名称随便,不是固定的,但是使用的时候关键字传参的时候,要和这两个参数的名称对应好,可以通过设置参数来进行一个判断处理等操作

    2、注册信号:在__init__.py中注册信号

    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)

3. django的读写分离

  • django的读写分离简述:

    django做的其实是在数据库已经做好读写分离的情况下,怎么使用
  • 首先配置多个数据库,在settings配置文件中配置以下内容:

    DATABASES = {
    'default': { # 默认数据库,配置多个mysql数据也是ok的,混用数据库也是ok的
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
    'db2': { # 配置的第二个数据库,注意数据库名字不能相同
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db2.sqlite3'),
    }
    }
  • 执行数据库同步指令,将默认数据库的表结构生成到db2这个数据库中

    python migrate --database db2(库名)
  • django使用读写分离

    1、手动实现,在views.py文件中进行操作时指定数据库

    def dbtest(request):
    data = []
    # 向db2数据库中写入数据
    models.Class.objects.using('db2').create(name='xx') # 从默认数据库中读取数据
    data = models.Class.objects.using('default').all()
    # 更新时
    for i in data:
    i.name = '张三'
    i.save(using='default') # 更新时指定数据库
    return render(request,'dbtest.html',{'data':data})

    2、自动实现,进行相关配置

    # 在应用文件夹中创建一个py文件,比如叫做router.py文件,写如下内容:
    
    class Router:
    def db_for_read(self,model,**kwargs):
    return 'default' def db_for_write(self,model,**kwargs):
    return 'db2'
    # settings配置文件做如下配置
    
    DATABASE_ROUTERS = ['app01.router.Router',]
    # []中写上面Router类的路径
    # 在views.py中,进行读写操作时,会自动操作不同的数据库
    
    def dbtest(request):
    data = []
    # 向db2数据库中写入数据
    models.Class.objects.create(name='李四') # 从默认数据库中读取数据
    data = models.Class.objects.all() return render(request,'dbtest.html',{'data':data})
  • 一主多从的时候,也就是从多个数据库中读取的时候:

    1、多个数据库进行随机读取的

    import random
    class Router:
    def db_for_read(self,model,**kwargs):
    print(model._meta.app_label)
    return random.choice(['db1','db2','db3']) # 多个库读的时候,可以简单的写个随机选择 def db_for_write(self,model,**kwargs):
    return 'db2'

    2、根据不同的应用来选择不同的库进行读取

    class Router:
    def db_for_read(self,model,**kwargs):
    print(model)
    print(dir(model)) # 其中有个_meta属性很有用
    app_name = model._meta.app_label # 获取当前model对象所在的应用名称
         m = model._meta.model_name # 获取当前操作的model对象的表名,也可以根据表名来进行多数据库读的分配 # 可以根据应用选择不用的库来进行读取
    if app_name == 'app01':
    return 'db1'
    elif app_name == 'app02':
    return 'db2'
    return 'default' def db_for_write(self,model,**kwargs):

Django13 /缓存、信号、django的读写分离的更多相关文章

  1. docker配置mysql主从与django实现读写分离

    一.搭建主从mysql环境 1 下载mysql镜像 docker pull mysql:5.7 2 运行刚下载的mysql镜像文件 # 运行该命令之前可以使用`docker images`是否下载成功 ...

  2. django数据库读写分离

    django数据库读写分离 1. 配置数据库 settings.py文件中 用SQLite: DATABASES = { 'default': { 'ENGINE': 'django.db.backe ...

  3. Nginx反向代理 负载均衡 页面缓存 URL重写及读写分离

    大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统 ...

  4. Django 数据库读写分离 分库分表

    多个数据库 配置: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BA ...

  5. django数据库读写分离,分库

    读写分离 在settings中配置不同名称的数据库连接参数,并配置一条数据库选择路由 DATABASES = { 'default': { 'ENGINE': 'django.db.backends. ...

  6. Django:实现读写分离

    库的配置 1.读写分离 settings配置 #settings.py 配置库信息,生成2个库 DATABASES = { 'default': { 'ENGINE': 'django.db.back ...

  7. 搭建MySQL主从实现Django读写分离

    一.MySQL主从搭建 主从配置原理: 主库写日志到 BinLog 从库开个 IO 线程读取主库的 BinLog 日志,并写入 RelayLog 再开一个 SQL 线程,读 RelayLog 日志,回 ...

  8. MySQL多数据源笔记2-Spring多数据源一主多从读写分离(手写)

    一.为什么要进行读写分离呢? 因为数据库的"写操作"操作是比较耗时的(写上万条条数据到Mysql可能要1分钟分钟).但是数据库的"读操作"却比"写操作 ...

  9. Mycat实现mysql主从复制(读写分离)

    数据库性能瓶颈主要原因: 随着用户数的增多,带来的是数据库连接的大幅度增长 随着业务体量的增长,表数据量(空间存储的问题)的大幅增长,其中涉及到索引的优化,mysql默认的索引是硬盘级别的,BTREE ...

随机推荐

  1. arduino连接1602LCD方法

    arduino连接1602LCD方法 参考代码:

  2. Spring事务方法上增加synchronized真的有效果吗?

    此文转载,Spring事务本身是一个非常复制的问题,再加上线程并发处理就更加要主要了,由于再开发中有很多朋友会范与下文同样的错误,因分享给大家. 前言 Spring事务的一个奇怪的问题. 朋友问了我一 ...

  3. Github删除分支下所有提交记录

    [本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 有时候,我们提交 ...

  4. 「从零单排canal 03」 canal源码分析大纲

    在前面两篇中,我们从基本概念理解了canal是一个什么项目,能应用于什么场景,然后通过一个demo体验,有了基本的体感和认识. 从这一篇开始,我们将从源码入手,深入学习canal的实现方式.了解can ...

  5. Redis设置并查看最大连接数

    在 Redis2.4 中,最大连接数是被直接硬编码在代码里面的,而在2.6版本中这个值变成可配置的. maxclients 的默认值是 10000,你也可以在 redis.conf 中对这个值进行修改 ...

  6. leetcode 力扣 两数之和

    class Solution: def addTwoNumbers(self, l1, l2): n1 = [] n2 = [] nl = [] while l1.next and l2.next: ...

  7. 01.scrapy入门

    Scrapy快速入门 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,它使用Twisted这个异步网络库来处理网络通讯,架构清晰,并且包含了各种中间件接口,可以灵活的完成各种需求. ...

  8. activiti学习笔记一

    activiti学习笔记 在讲activiti之前我们必须先了解一下什么是工作流,什么是工作流引擎. 在我们的日常工作中,我们会碰到很多流程化的东西,什么是流程化呢,其实通俗来讲就是有一系列固定的步骤 ...

  9. spring boot 和shiro的代码实战demo

    spring boot和shiro的代码实战 首先说明一下,这里不是基础教程,需要有一定的shiro知识,随便百度一下,都能找到很多的博客叫你基础,所以这里我只给出代码. 官方文档:http://sh ...

  10. openstack-taskflow 组件记录

    [Summary] TaskFlow 是一个为了 openstack 实现的 python 库,使得执行 task 变得简单,一致,易扩展,可靠: 它能以一种声明的方式,将轻量级 task 对象的创建 ...