Django个人博客开发(九)文章点击次数
发布时间:2018-04-14 12:04:15分类:编程开发阅读:1319
概述
每阅读一次文章,文章点击次数加一,为了不频繁进行数据库的读写,操作文章点击次数,使用redis键值对缓存文章点击次数。
阅读文章时,要实时更新点击次数;显示文章列表或详情时,要获取当前文章点击次数;要永久保存文章点击次数,则需要将缓存同步到数据库中。因此,对文章点击次数的操作主要可分为三个部分:
(1)更新当前文章点击次数,upadate_article_hits()
(2)获取当前文章点击次数,get_article_hits()
(3)同步所有文章点击次数,syn_article_hits()
更新和获取文章点击次数是针对当前文章对象,因此可以定义文章的数据模型方法,这样文章的实例对象可以直接调用方法更新或获取其点击次数。
文章点击次数思路

1、准备redis环境
Redis服务器环境搭建网上搜索。
2、在xdsite/settings.py中配置以redis作为django的cache缓存后端
# Cache
# cache 配置为Redis Backends
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
3、在blog应用目录下创建缓存管理的python包cache_manager
目录结构如下:

其中,
__init__.py为python包必需的文件,其中定义了__all__变量,指定了update_article_hits和get_article_hits两个函数,用于在导入包时,直接导入这两个方法,实现模糊导入;
Cache_manager.py 中定义了update_article_hits()和get_article_hits()两个函数,针对缓存操作文章点击次数;
Cache_sync.py 中定义了syn_article_hits()函数,用于同步缓存与数据库的点击次数;
注意:
因为syn_article_hits()函数需要对文章数据模型Article操作,而update_article_hits()和get_article_hits()两个函数需要在文章数据模型方法中调用,为了避免冲突,因此将syn_article_hits()与另外两个函数分作两个文件。
4、编辑cache_manager.py文件
# -*- encoding: utf-8 -*-
from django.core.cache import cache
def update_article_hits(article):
"""更新文章点击次数"""
# 指定key不存在则从数据库hits字段添加,并设置永不过期
cache.add("article:{}:views".format(article.id), article.hits, timeout=None)
# 指定key的值自增1
cache.incr("article:{}:views".format(article.id))
5、编辑cache_sync.py文件
# -*- encoding: utf-8 -*-
from blog.models import Article
from django.shortcuts import get_object_or_404
from django.core.cache import cache
def syn_article_hits():
"""将redis缓存中的点击次数同步到数据库中"""
for key in cache.keys("article:*:views"):
# 从key中获取文章id值
article_id = int(key.split(':')[1])
try:
article = get_object_or_404(Article, id=article_id)
# 如果数据库中的点击次数大于缓存的值,则更新缓存中的值,否则将缓存中的值存入数据库中
if article.hits > int(cache.get(key)):
cache.set(key, article.hits)
else:
article.hits = int(cache.get(key))
article.save()
except:
# 数据库中已不存在该文章则redis删除该键
cache.delete(key)
6、编辑__init__.py文件
__author__ = 'xdao07'
from .cache_manager import update_article_hits, get__article_hits
__all__ = [
"update_article_hits", "get__article_hits"
]
7、在文章数据模型Article中,定义数据模型方法
from .cache_manager import get__article_hits, update_article_hits
# 文章表数据模型
class Article(models.Model):
……省略部分……
# 更新缓存中的文章点击次数
def update_hits(self):
update_article_hits(self)
# 从缓存获取文章点击次数
def get_hits(self):
return get__article_hits(self)
8、在文章详情视图views.py/article_detail()中添加文章对象方法,实时更新文章点击次数
# 文章详情页视图
def article_detail(request, id, slug):
# 返回匹配id和slug的文章对象,否则的404错误
article = get_object_or_404(Article, id=id, slug=slug)
# 更新当前文章点击次数
article.update_hits()
return render(request, 'blog/article.html', locals())
9、在文章列表和文章详情模板页中完善文章阅读次数显示
9.1文章列表,文件blog/baseblock/list.html
<p class="dateview"><span>{{ article.publish | date:'Y-m-d' }}</span><span>阅读:{{ article.get_hits }}次</span><span>个人博客:[<a href="{% url 'blog:article_list' article.category.id %}">{{ article.category.name }}</a>]</span></p>
9.2文章详情,文件blog/article.html
<p class="box_p"><span>发布时间:{{ article.publish | date:'Y-m-d H:m:s' }}</span><span>分类:{{ article.category.name }}</span><span>阅读:{{ article.get_hits }}</span></p>
10、把同步文章点击次数添加到文章列表页视图,在每次请求列表时将缓存中的点击次数同步到数据库(不提倡,依旧频繁读取库)
from .cache_manager import cache_sync
def article_list(request, category_id=None, tag_id=None, page=1):
# 同步缓存和数据库中的文章点击次数
cache_sync.syn_article_hits()
……省略部分……
11、在RUL路由配置文件blog/urls.py中指定一个接口,用于手动和添加计划任务更新文章点击次数(注释掉10中添加的cache_sync.syn_article_hits()行)
11.1 在视图文件blog/views.py中添加视图函数
from django.http import HttpResponse
from .cache_manager import cache_sync
# 同步缓存和数据库中的文章点击次数
def sync_hits_cache_to_db(request):
cache_sync.syn_article_hits()
# 返回指定字符串到客户端
return HttpResponse('Sync hits between cache and db.')
11.2 在URL路由文件blog/urls.py中添加路由
urlpatterns = [
……省略部分……
# 通过指定路由到指定视图将执行同步函数
url(r'^sync-hits-cache-to-db/$', views.sync_hits_cache_to_db, name='sync_hits_cache_to_db'),
]
11.3 重启项目,检测路由是否能同步点击次数
代码查看:https://github.com/xdao07/xdsite/tree/v0.0.6
代码下载:git clone --branch v0.0.6 https://github.com/xdao07/xdsite.git