Django包含一个contenttypes
应用程序,可以跟踪Django支持的项目中安装的所有模型,为您的模型提供高级通用接口。
安装contenttypes框架
contenttypes
框架默认是被安装在INSTALLED_APPS
中的,
如果删除了它可以用, django.contrib.contenttypes
安装回来
安装contenttypes框架通常是个好主意; Django的其他几个捆绑应用程序需要它:
- 管理应用程序使用它来记录通过管理界面添加或更改的每个对象的历史记录。
- Django 使用它将用户权限绑定到特定模型。
实现博客系统的点击量功能
- 首先要创建一个app, 这个app让它只实现需要的计数功能,这样符合django设计理念
- 我现在想要在我的xadmin里显示点击量
models.py
class ReadNum(models.Model):
"""
阅读次数统计
"""
read_num = models.IntegerField(default=0, verbose_name='阅读次数')
content_type = models.ForeignKey(ContentType, on_delete=models.DO_NOTHING,
verbose_name="计数类型")
object_id = models.PositiveIntegerField(verbose_name='类型id')
contentObject = GenericForeignKey('content_type', 'object_id')
def show_content(self):
return "标题: %s" %(self.contentObject.title)
- read_num是我们需要的字段
- 不要忘记迁移文件
类GenericForeignKey
设置一个有三个部分 GenericForeignKey
- 给你的模型
ForeignKey
来设置ContentType
。该字段的通常名称是“content_type”。 - 为您的模型提供一个字段,该字段可以存储您要与之相关的模型中的主键值。该字段的通常名称是“object_id”。
-
GenericForeignKey
,传递上述两个字段的名称。如果这些字段名为“content_type”和“object_id”,则可以省略 - 这些是GenericForeignKey
将要查找的默认字段名称 。
models.py
定义一个方法, 用于xadmin显示点击量
class ReadNumExpandMethod():
def get_read_num(self):
try:
ct = ContentType.objects.get_for_model(self)
readnum = ReadNum.objects.get(content_type=ct, object_id=self.pk)
return readnum.read_num
except exceptions.ObjectDoesNotExist:
return 0
- 让我的博客模型继承这个方法
class Blog(models.Model, ReadNumExpandMethod):
blog_type = models.ForeignKey(BlogType, on_delete=models.DO_NOTHING, verbose_name="博客类型")
title = models.CharField(max_length=50, verbose_name="标题")
content = UEditorField(verbose_name=u"内容", imagePath="blog/content/",
filePath="blog/files/",)
author = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="作者")
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建日期")
last_updated_time = models.DateTimeField(auto_now=True, verbose_name="更新日期")
def __str__(self):
return "<Blog: %s>"% self.title
class Meta:
ordering = ["-created_time"]
adminx.py
用于显示这个字段
class BlogAdmin(object):
list_display = ["title", 'blog_type', "content", "author", 'get_read_num', "created_time", "last_updated_time"]
style_fields = {"content": "ueditor"}
xadmin.site.register(Blog, BlogAdmin)
- 正常Get read num 字段都是0, 我现在还不会设置附加字段的名字 和颜色
实现访问博客点击量就增加的功能
- 在创建一个utils文件,
utils.py
import datetime
from django.contrib.contenttypes.models import ContentType
from .models import ReadNum, ReadDetail
from django.db.models import F
from django.utils import timezone
from django.db.models import Sum
def read_statistics_once_read(request, obj):
"""
阅读一次增加阅读量
:param request:
:param obj:
:return:
"""
ct = ContentType.objects.get_for_model(obj)
key = "%s_%s_read" % (ct.model, obj.pk)
if not request.COOKIES.get(key):
# 阅读总数 +1
readnum, created = ReadNum.objects.get_or_create(content_type=ct, object_id=obj.pk)
readnum.read_num += 1
readnum.save()
return key
- 在
blog
下的view.py
def blog_detail(request, blog_pk):
"""
博客详细
:param request:
:param blog_pk:
:return:
"""
blog = get_object_or_404(Blog, pk=blog_pk)
read_cookie_key = read_statistics_once_read(request, blog)
context = {}
context["previous_blog"] = Blog.objects.filter(created_time__gt=blog.created_time).last()
context["next_blog"] = Blog.objects.filter(created_time__lt=blog.created_time).first()
context['blog'] = blog
response = render_to_response('blog/blog_detail.html', context)
response.set_cookie(read_cookie_key, 'true') # 阅读cookie标记
return response
这样就可以每次看文章的时候点击量都会加1, 并且设置了cookie就会让点击量更加真实