【DailyFresh】课程记录

Django内置认证系统文档:

http://doc.codingdict.com/django/topics/auth/default.html#user-objects

P27 登录装饰器和登录后页面跳转

1. 在user的urls中配置装饰器login_required

2.去settings.py中配置LOGIN_URL(这是要重定向到的地址)

3.修改login的视图函数逻辑,获取next_url,如果没有next则默认跳转到goods的首页

【关于装饰器login_required】

P28 LoginRequiredMixin类的使用

1.在urls中加装饰器login_required看起来不美观且麻烦,因此将其单独写在utils包中,utils--->mixin.py---->LoginRequiredMixin类

2.需要进行登录验证的类继承LoginRequiredMixin类即可

P29 LoginRequiredMixin类的原理

在访问127.0.0.1//user之后,进行路由匹配找到UserInfoView.as_view(),UserInfoView类中没有as_view(),因此会去它的父类中找as_view(),可以看到此时它继承了两个类,因此会先去它的第一个父类LoginRequiredMixin中找,调用该类中的as_view().随后会向他的父类View中调用as_view()

class UserInfoView(LoginRequiredMixin, View)

P30 登录后欢迎信息

1.如果用户没有登录,欢迎栏显示【登录|注册】,如果登录了则应该显示【欢迎您:xxx】。

2.参考django文档中的【Web请求中的认证】部分。

3.Django框架本身会给request对象增加一个user属性,表示当前用户。如果用户未登录,则是AnonymousUser类的一个实例;如果用户登录,则是User类的一个实例。两者均有is_authenticated()方法,用户未登录时该方法返回False,用户登录时该方法返回True。

4.除了你给模板文件传递的模板变量之外,django框架会把request.user也传给模板文件。

5.因此,这里在模板中使用user.is_authenticated()方法进行判断即可。

P31 退出用户登录

1.参考django文档中的【如何登出一个用户】部分

2.编写LogoutView视图类

3.在urls中添加logout路由

4.退出登录后页面会跳转至商品首页

P32 登录判断——欢迎信息_退出登录小结

P33 用户中心_地址页

1.在提交get请求时,用户中心三个页面需要获取到的信息

2.用户中心-个人信息页面:

获取用户的个人信息

获取用户的历史浏览记录

3.用户中心--订单页面

获取用户的订单信息

4.用户中心---地址页面

获取用户的默认地址信息

5.【地址页面】

包括了展示默认收货地址以及一个表单提交新增收货地址

post请求处理流程:

接收数据---》数据校验---》业务处理:添加地址---》返回响应

在进行业务处理时:

如果用户已存在默认收货地址,添加的地址不作为默认收货地址,否则作为默认收货地址。

django会给request对象添加一个user属性,这里只有已登录才能访问到该页面,因此可以获取到登录用户对应User对象

通过获取的user对象进行查询,如果不存在默认收货地址,进行try...except Address.DoseNotExist捕获异常

根据address的值来决定is_default的值

添加地址操作

返回应答,刷新地址页面,即重定向到当前页面,本质上是进行get请求

get请求处理流程:

获取登录用户对应User对象

获取用户的默认收货地址

使用模板传入默认收货地址address,进行展示

P34  模型管理器类方法封装

这一节主要通过自定义一个模型管理器类封装方法,用于获取用户的默认地址

获取默认收货地址,即根据某一条件查询用户的默认收货地址,通过objects对象查找【Django为每个模型类生成的模型管理对象】《---models.Manager的对象

自定义一个模型管理器类

作用1: 改变原有查询的结果集all()

作用2:封装方法:用于操作模型类对应的数据表(增删改查)

自定义一个模型管理器对象

self.model<---获取self对象所在的模型类

P35 用户中心---个人信息页

1.需要获取用户个人信息,包括用户名,联系方式以及地址

2.在获取用户名的时候直接用request.user即可

3.在获取用户的联系方式以及地址时,根据模型管理器类获取address

4.在展示联系方式以及地址时,通过判断address是否存在,若存在,则进行展示 ,否则展示部分写【无默认】

P36 历史记录存储格式设计

Redis存储历史浏览记录

1. 什么时候需要添加历史浏览记录?
访问商品的详情页面的时候(在商品详情对应的视图中), 需要添加历史浏览记录。

2. 什么时候需要获取历史浏览记录?
访问用户中心-个人信息页的时候获取历史浏览记录

3. 历史浏览记录需要存储在哪里?
redis数据库---》内存型的数据库
使用redis数据库存储历史浏览记录

4. redis中存储历史浏览记录的格式?
string
hash
list
set
zset

case1:存储用户的历史浏览记录时,所有用户的历史浏览记录用一条数据保存
hash:
history:user_用户id:'1, 2, 3'

case2: 每个用户的历史浏览记录用一条数据保存
list:
history_用户id:[2, 3, 1]
添加历史浏览记录时,用户最新浏览的商品id从列表左侧插入。

P37 获取用户历史浏览记录


总结:连接到redis---》拼接history_key---》获取用户最新浏览的5个商品id,得到返回列表---》获取用户浏览的商品信息,查询出的顺序需要与用户浏览顺序保持一致---》组织context,传给模板
【目前暂时没有详情页面,已分析获取方法和过程,因此很容易可以获取该信息】
1.历史浏览记录存放在redis中
2.从redis数据库中找到已存储的浏览记录
3.settings中有缓存配置,这里的历史浏览记录也存放在该缓存中
4.获取用户的历史浏览记录
    # way1:之前拿链接的方法
    导入redis
    创建StrictRedis对象
    redis与Python进行交互时,如何创建sr对象 
        # from redis import StrictRedis
        # sr = StrictRedis(host='127.0.0.1', port='6379', db=9)
    
    # way2:使用django-redis的方法拿链接的方式
    from django-redis import get_redis_connection
    con = get_redis_connection('default')
    
    取出用户的浏览记录,创建history_key
    获取用户最新浏览的五个商品的id
    从数据库中查询用户浏览的商品的具体信息(导入GoodsSKU类并进行查询)这里有两种方式,第一种是先根据id__in获取到数据,再按照浏览顺序依次放入list中,第二种是遍历获取用户浏览的历史商品信息
    将传送给模板的参数组织上下文context

P38 FastDFS文件系统简介


Client---Track_server---Storage_server
Track_server(调度服务器):负载均衡和调度
Storage_server(存储服务器):文件存储

FastDFS的特点:
1. 海量文件存储
2. 存储容量扩展方便
3. 同样文件内容在FastDFS中只存储一份

P39 FastDFS上传文件和下载文件流程


文件上传流程:
1.客户端请求Track-server
2.Track-server查询可用的storage_server
3.返回可用storage_server的IP和端口号
4.client直接访问storage_server的IP和端口号,将文件进行上传
5.storage_server将文件存储之后会生成一个file_id,将文件内容写到相应的磁盘上面,并返回file_id.
6.该文件ID(即file_id)用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。

文件下载流程:
1.客户端请求Track-server
2.Track-server根据要下载的文件查找其所在Storage_server
3.将查找到的Storage_server的IP和端口号返回给client
4.客户端根据IP和端口号查找对应的Storage_server,并获取文件
5.Storage_server根据file_id查找对应的文件,并将其返回给client。

P40 FastDFS的安装和配置


1.安装FastDFS的依赖包
2.安装FastDFS
3.配置调度服务器Track-server
sudo vim tracker.conf 
base_path=

4.配置存储服务器Storage-server
sudo vim storage.conf 
base_path=
store_path0=/home/python/fdfs/storage
tracker_server = IP:22122 # 管理Storage的tracker_server

5.上传文件测试
fdfs_upload_file /etc/fdfs/client.conf 要上传的图片文件


P41 Nginx配合FastDFS使用的安装和配置


FastDFS在用户访问量比较大的时候获取的效率比较慢,这里借助一个web服务器nginx,配合FastDFS使用【在提供静态文件方面效率很高】
nginx接收请求的时候使用的是epoll

1. 下载并解压缩nginx-1.18.0.tar.gz

2. 下载并解压缩fastdfs-nginx-module-master.zip

3. 进入nginx-1.18.0目录,执行预编译命令
sudo ./configure --prefix=/usr/local/src/nginx/ --add-module=fastdfs-nginx-module-master解压后的目录的绝对路径/src
prefix后面跟的是nginx安装好之后要安装到哪一个路径下方
如:
sudo ./configure --prefix=/usr/local/src/nginx/ --add-module=/usr/local/src/fastdfs-nginx-module-master/src

sudo make
sudo make install

4. 
sudo cp fastdfs-nginx-module-master解压后的目录中src下的mod_fastdfs.conf /etc/fdfs/mod_fastdfs.conf
如:
sudo cp /usr/local/src/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/mod_fastdfs.conf

5. 修改/etc/fdfs/mod_fastdfs.conf中的内容
connect_timeout=10
tracker_server=自己的IP:22122
url_have_group_name = True # 访问FastDFS时带不带组信息
store_path0=/home/python/fdfs/storage

6.sudo cp 解压缩的fastdfs-master目录中conf目录下的http.conf /etc/fdfs/http.conf
如:
sudo cp /usr/local/src/fastdfs-master/conf/http.conf /etc/fdfs/http.conf

7. sudo cp 解压缩的fastdfs-master目录中conf目录下的mime.types /etc/fdfs/mime.types
如:
sudo cp /usr/local/src/fastdfs-master/conf/mime.types /etc/fdfs/mime.types

8.编辑nginx的配置文件
sudo vim /usr/local/src/nginx/conf/nginx.conf 

http---使用的协议
    server {
        listen       8888;
        server_name  localhost; #服务器域名
    # location相当于在django中配置中的url
    # 只要访问nginx的时候地址中出的group,nginx就会去找 ngx_fastdfs_module
        location ~/group[0-9]/ {
            ngx_fastdfs_module; 
        }

9.启动nginx

cd /usr/local/src/nginx/sbin
sudo ./nginx


P42 python和FastDFS交互 

使用Python客户端上传测试
在项目的环境下安装fdfs_client包,命令如下
pip3 install fdfs_client

P43 虚拟机中FastDFS配置文件的修改


启动FastDFS的方法,需要的操作:
1.修改如下配置文件:
/etc/fdfs目录中的client.conf、mod_fastdfs.conf、storage.conf文件

tracker_server=自己的IP地址:22122

2.启动tracker、Storage、nginx服务:
sudo service fdfs_trackerd start
sudo service fdfs_storaged start
sudo /usr/local/nginx/sbin/nginx

3.执行如下命令测试是否成功
fdfs_upload_file /etc/fdfs/client.conf 要上传的图片文件
若返回类似group1/M00/00/00/wKgAZ2ASnquASyohAAA94WZln4k51.jpeg的文件id,则说明文件上传成功

在浏览器中可以用127.0.0.1:8888/返回的文件id访问上传的图片

P44  项目中上传和使用图片的流程

38-43:介绍了FastDFS,关于FastDFS,我们需要知道,为什么要应用在我们的系统中,解决了什么问题【1.文件的海量存储;2.存储容量的扩展比较方便;3.文件内容防止重复,即同样内容的文件在FastDFS中只存储了一份】 结合nginx提供的静态文件,我们的整个网站提供静态文件的速度也有了提升

在我们的项目中如何处理:
之前:
通过admin页面上传图片之后是保存在media_root指定的目录下方,而现在是要保存在FastDFS文件存储服务器中

Django结合上传文件到FastDFS中的流程:
浏览器请求上传文件,由django把文件上传到FastDFS,FastDFS在上传完文件之后会返回一个文件id,最终将文件id保存到表里面

项目中使用图片的流程:
浏览器请求某一页面(如:/user)


上传流程:
运营人员,后台管理人员通过admin界面上传商品的图片,选择好图片之后点击上传,此时浏览器会向django服务器发送一个请求(请求上传文件),django服务器会把文件上传到FastDFS,FastDFS在保存完文件之后会返回一个文件id,该文件id会保存在对应的表中,该表中有一个名为image的字段。
如何展示图片:

当用户访问页面的某一个地址时,如果在页面上用到该图片,则在渲染页面时,需要把该图片的src写成相应的路径,http://nginx的ip:port/文件id,渲染之后会将内容返回给浏览器,浏览器在显示页面的时候,当页面中出现的img标签时,浏览器就会去访问src中的地址,访问的目的就是获取该图片,此时浏览器请求nginx获取图片,nginx从FastDFS中将文件找出来,找出来之后返回图片内容,此时即可显示图片。在此后浏览器请求图片,并获取到返回内容,已经不需要经过django服务器。

 


P45 自定义文件存储类

对django进行二次开发
之前django默认上传文件时,通过后台管理页面,选择一个文件进行保存的时候,使用的是FileSystemStorage类,其中的save方法实现文件的保存,该方法默认将文件保存至media_root指定的文件目录下方。

要保存到FastDFS中,需要自定义文件存储:扩展Storage类,更改文件存储行为。
编写自定义存储系统

1.在某个远程系统上存储文件。
2.可以通过自定义存储类实现,该存储类必须为Storage类的子类。
3.自定义存储类必须实现_open()方法和_save()方法。其中open方法用于打开文件、save方法用于存储文件

定义了一个FDFSStorage类【_open()方法、_save()方法、_exists()方法】
open方法用于打开文件,这里无需实现
save(name, content)方法用于存储文件
    # name:你选择的上传文件的名字
    # content: 包含你上传文件内容的对象,是File类对象,其中的read()方法可读取文件内容
    
    1. 创建Fdfs_client对象,实现Python与FastDFS的交互 (需要指定client配置文件,记得修改base_path和tracker_server)
    2. 根据文件内容将其上传至fast_dfs系统中。client.upload_by_filename是根据文件名字上传至FastDFS系统,client.upload_by_buffer是根据文件内容上传至FastDFS系统。
    3. 根据Step2返回的字典中的Status字段判断文件上传是否成功,若失败则抛出异常,此处为了通用性,仅抛出异常,不作处理。
    4. 获取Step2返回字典中的文件ID
    5. 返回文件ID

django在调用save之前会先调用exists方法,判断文件名是否可用(逻辑是:如果提供的名称所引用的文件在文件系统中存在,则返回True,否则,如果这个名称可用于新文件,返回False。)。此处文件名为FastDFS返回,文件名不涉及是否可用的问题,故exists方法直接返回False即可。

P46 admin页面测试文件存储类

设置django的文件存储类
修改settings.py的配置DEFAULT_FILE_STORAGE
其默认配置为:

修改后的配置为:


测试(以GoodsType为例):
1.在admin中注册GoodsType

admin.site.register(GoodsType)

2. 创建一个superuser并登录
3. 通过admin页面上传一个图片
4.点击之后会需要一个url方法---该方法返回URL,通过它可以访问到name所引用的文件
url(self, name)----返回访问文件的URL路径 
    # name即为save方法中返回的filename

P47 改进自定义文件存储类


优化FDFSStorage类,使得代码可动态配置

当前的client.conf配置文件是硬编码,url返回的nginx的IP和端口也是硬编码。这里通过__init__中初始化并传参
在settings.py中:
设置fdfs使用的client.conf文件路径     
设置fdfs存储服务器上nginx的IP和端口号 

P48 FastDFS上传图片小结

海量存储
存储容量扩展方便
文件内容重复
结合nginx提高网站提供图片的效率

 

 P56 商品模型类概述


搭建商品模块部分的框架,包括路由匹配、首页框架展示、模型类介绍

P57 首页内容获取和展示

首页无表单等内容,仅做展示【本质上都是查询信息】
1. 获取商品的种类信息
2. 获取首页轮播商品信息(带排序)
3. 获取首页促销活动信息(带排序)
4. 获取首页分类商品展示信息
这一步为了方面在首页展示时,进行遍历展示,进行如下处理
遍历Step1中获取到的商品的种类信息;
获取每个type种类首页分类商品的图片展示信息,这里记得带排序
获取每个type种类首页分类商品的文字展示信息,这里记得带排序
动态给Type增加属性,分别保存首页分类商品的图片展示信息和文字展示信息
5. 获取用户购物车中商品的数目

导入必要的商品模型类
实现获取信息
组织模板上下文context


在首页进行显示
种类信息遍历显示,href中可以用模板语言的for循环遍历中有{{forloop.counter }}变量,即从1往后开始数

P58 首页内容获取和展示小结


本质上就是从数据库中查询内容并进行展示


P59 redis存储购物车记录分析


首页购物车信息,需要查看购物车中商品的数目
分析:
1. 什么时候添加购物车记录?
用户点击加入购物车,detail页面和list页面购物车标识
2. 什么时候获取购物车记录?
使用购物车中数据,如首页&&访问购物车页面的时候需要获取购物车记录
3. 使用什么存储购物车记录?
Redis存储购物车记录
4. 分析存储购物车记录格式
一个用户的购物车记录用一条数据保存

需要存储商品SKU_id以及加入购物车的数量
使用hash保存
'cart_用户id':{'sku_id1': 商品数目, 'sku_id2': 商品数目}
例子:
'cart_1': {'1': 3, '2': 5}
获取用户购物车中商品的条目数:使用hlen

String
list
hash 属性和值
set
zset

P60 首页获取购物车商品数目

1.导入django_redis的get_redis_connection
2.默认购物车商品数目显示0。判断用户是否登录。若已登录,拿到连接,生成cart_key,并通过conn.hlen(cart_key)拿到用户购物车条目数

from django-redis import get_redis_connection

cart_count = 0

if user.is_authenticated():
    # 如果用户已登录,则获取用户购物车信息
    conn = get_redis_connection('default')
    cart_key = 'cart_%d' %user.id
    cart_count = conn.hlen(cart_key)


在base.html中有一个显示购物车数量

模拟添加至购物车
redis-cli 
select 9
keys *
去数据库中查询用户id,比如user_id=2,hmset cart_2 1 3 2 5
keys *(此时会有加入的相关信息)

hlen cart_2


P49 页面静态化_celery生成首页静态页面

进行网站优化操作【首页页面静态化,在celery中定义一个任务函数】
用户访问网站必先访问首页
首页不常变化
将首页页面生成相应的静态页面 

考虑:
什么时候需要重新生成静态页面?
当管理员后台修改首页信息对应的表格中的数据的时候,需要重新生成首页静态页


在celery中定义一个任务函数
和查询首页数据的处理方法一样----放入到任务函数generate_static_index_html中
此处无需购物车信息
此时生成的是用户未登录的页面信息,重新定义一个static_base.html,重新定义一个static_index.html
render返回的是HttpResponse对象,这里只需要获取内容即可,不需要返回HttpResponse对象,在此使用之前模板使用的步骤
1.加载模板文件,返回模板对象
temp = loader.get_template('static_index.html')
2.定义模板上下文,用到的数据需要传过去
context = RequestContext(request, context)
3.模板渲染,产生替换后的内容
static_index_html = temp.render(context)
需要借助from django.template import loader, RequestContext,在模板渲染的时候可以传入一个RequestContext对象也可以直接传入一个context字典,此时也可以将模板文件中对应的变量使用传入的context字典中的数据进行替换,并返回替换后的内容。


至此首页页面的内容已有,接下来需要生成首页对应的静态页面文件,生成在static文件夹下面
生成保存路径
save_path = os.path.join(settings.BASE_DIR, 'static/index.html')
with open(save+path, 'w') as f:
    f.write(static_index_html)


该任务函数的作用:
1.查询首页数据
2.将获取的数据传给模板文件
3.得到渲染后的内容,将其写入某一文件中,生成对应的静态文件
4.记得进行@app.task装饰


启动worker
1.进入虚拟环境
2.该任务有一部分依赖django环境,在启动之前需要进行配置,即初始化
3.启动celery的worker,命令如下:
celery -A celery_tasks.tasks worker -l info 
4.最终生成的页面会放在static下方,这里需要提前删除worker端已有的index.html
5.此时worker已启动,要生成静态页面,只需要发出任务即可
6.在本项目命令行下进行测试
from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()

此时页面在worker端生成成功,下一节考虑如何访问生成的页面。


P50 配置nginx提交静态页面

通过celery已经成功生成处页面,接下来访问生成的页面。

1.启动一个celery服务器
2.django发出一个生成首页页面的任务generate_static_index_html
3.celery服务器这边会生成一个index.html静态文件
4.用户访问页面,如何进行显示
5.nginx可以帮助我们提供celery服务器端的静态页面,用户直接访问nginx即可获取页面。因此在celery上部署一个nginx,由它提供静态页面。
6.celery服务器所在电脑上的nginx如何配置
7.此时已经安装nginx,只需要在nginx配置文件中加上配置项即可
进入nginx安装位置
cd /usr/local/src/nginx/
打开nginx配置文件
sudo vim ./conf/nginx.conf
在该配置文件中一个server可以认为是一个web服务器

server {
    listen    80;
    server_name    localhost;
    
    # 可以认为是一个URL的配置项
    # 根据浏览器中输入的访问地址会去匹配nginx配置项
    location /static {
        alias    /home/python/xxx/dailyfresh/static;
    }
    
    # root配置项:是一个指定的目录
    location / {
        root /home/python/xxx/dailyfresh/static/;
        index index.html index.htm;
    }
}

8.重启修改配置项之后重启nginx服务
sudo sbin/nginx -s reload
9.在浏览器中输入127.0.0.1访问,没写端口号会默认访问80端口,随后根据配置文件中的配置项到配置的目录下方找到index.html并返回

这里有可能会遇到nginx 403 forbidden的情况

解决方案:这位大佬列的很详尽

https://blog.csdn.net/qq_35843543/article/details/81561240


P51 admin管理更新首页数据表数据时重新生成index静态页面

上一节是静态页面的生成以及通过nginx提供静态页面
后台管理员通过浏览器修改首页对应的表中的数据
1. 修改表中数据
2.Django让celery重新生成静态页面,即django需要想celery发出任务generate_static_index_html


Django admin站点有关的一个类

每一个后台管理页面都会有一个模型管理类,需要继承admin.ModelAdmin
在ModelAdmin中有save_model和delete_model方法
当后台管理员去添加或者更新表中的数据的时候,对应的ModelAdmin.save_model()方法会被调用
如果删除数据,则对应的ModelAdmin.delete_model()方法会被调用
所以我们需要在这两个方法内部添加附加操作,即让其重新生成首页的静态页面

1.定义模型类对应的模型管理类,通过其中的一些属性可以控制后台管理页面显示的内容

from goods.models import GoodsType, IndexGoodsBanner, IndexTypeGoodsBanner, IndexPromotionBanner
from celery_tasks.tasks import generate_static_index_html

class IndexGoodsBannerAdmin(admin.ModelAdmin):
    pass

admin.site.register(IndexGoodsBanner, IndexGoodsBannerAdmin)
当管理员修改IndexGoodsBanner表中对应的数据时,它就会去调用ModelAdmin中的save_model()方法。此时我们需要让它重新生成静态页面。此时进行方法的重写
class IndexGoodsBannerAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
     """新增或更新表中的数据时调用"""
    # 调用父类方法,进行更新或新增
        super().save_model(request, obj, form, change)

        # 发出任务,让celery worker 重新生成首页静态页
        # 为何在顶部导入不可以,执行celery会出错
        from celery_tasks.tasks import generate_static_index_html
        generate_static_index_html.delay()

删除操作同理,且所有表都进行类似处理,将重写后的save_model方法和delete_model方法进行抽象,抽象出BaseModelAdmin类。

 

P52 静态index页面和IndexView的调度说明


访问静态页面时,让用户访问的是nginx。
Django网站和nginx有可能不在同一台电脑上,我们如何让用户访问静态页面或者让用户直接访问Indexview返回的页面,两者需要做一个区分。

Django网站所对应的视图是一个Indexview,celery服务器上对应的是一个静态文件。在celery服务器上搭建一个nginx,由nginx提供静态文件。
现在的需求是,当用户输入一个地址,浏览器是需要访问django网站获取indexview的返回页面,还是nginx服务器提供的静态页面文件。
在此之前需要添加一个新的nginx服务器,进行调度,该服务器有自己的IP和地址,功能就是实现调度。

当用户访问网站时,只会给用户暴露一个IP,即用来调度的nginx的IP。
这里的调度规则:【调度部分部署的时候详述】
如果只访问nginx的IP时,则该nginx去访问celery服务器的nginx,获取静态页面文件;
如果在nginx的IP地址后面加了/index,则将该请求交给django网站。

此时Indexview对应的地址为/index

1. 使用celery生成静态页面
【任务函数generate_static_index_html】
2. 配置nginx提供静态页面
【sudo vim /usr/local/src/nginx/conf/nginx.conf】
3. 管理员修改首页所使用表中的数据时,重新生成index静态页面
【重写admin.ModelAdmin中的save_model和delete_model函数】

P53 首页数据缓存设置和获取

页面数据的缓存
把页面使用的数据存放在缓存中,当再次使用这些数据时,先从缓存中获取,如果获取不到,再去查询数据库。减少数据库查询的次数。
【django‘cache framework】
动态页面---每次用户请求页面,服务器都会重新计算。 
settings.CACHES,通过该配置项设置缓存

django支持的缓存形式:
memecache---内存型数据库,eg: Redis
数据库缓存
文件系统缓存
本地内存缓存
虚拟缓存

django中的缓存级别
站点级缓存---缓存整个网站数据。由于Redis的内存有限,这里不适用 
单个View缓存---使用@cache_page装饰器,缓存视图函数的返回内容。由于每次返回数据都不一样,这里不适用。
模板片段缓存---view已经查库完毕。。。不适用

这里直接操作底层的缓存API,自己设置读取缓存。
from django.core.cache import cache

接口set(key, value, timeout)---设置缓存
key: 缓存的名字
value: 缓存的内容
timeout: 缓存的过期时间
接口get(key)---根据key获取缓存

在首页页面中只需要缓存国定展示的列表内容
# 设置缓存 之前获取到的数据

from django.core.cache import cache

class IndexView(View):
    def get(...):
        """显示首页"""
        # 尝试从缓存中获取数据
        # 如果拿不到数据会返回None
        context = cache.get('index_page_data')

        if context is None:
            # 缓存中没有数据

            # 获取商品种类信息
            # 获取首页轮播商品信息
            # 获取首页促销活动信息
            # 获取首页分类商品展示信息

            # 组织上下文信息
            context = {
                'types': types,
                'goods_banners': goods_banners,
                'promotion_banners': promotion_banners,
            }

            # 设置缓存

            # key value timeout
            cache.set('index_page_data', context, 3600)
        # 获取用户购物车中商品的数目

        # 组织模板上下文
        # 字典中存在key值cart_count则进行更新,否则添加该键值对
        context.update(cart_count=cart_count)        
    
        # 使用模板


可以添加一条print访问两次进行测试or去redis中查看keys *
redis-cli -h IP
select 9
keys *
get [key]
注:访问127.0.0.1:8000/index


P54 首页缓存数据的更新


什么时候需要更新首页的缓存数据?
当管理员后台修改首页信息对应的表格中的数据的时候,需要更新首页的缓存数据

在admin的BaseModelAdmin中,

def save_model(...):
    # 调用父类admin.ModelAdmin中的save_model()
    # 发出任务,让celery work重新生成首页静态页
    # 清除首页的缓存内容
    cache.delete('index_page_data')

def delete_model(...)同理

P55 页面静态化和缓存数据_小结

首页页面的静态化和页面数据的缓存本质上是对网站本身性能的优化
减少数据库查询次数
防止恶意攻击,DDoS攻击

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值