Django包含一個contenttypes應(yīng)用程序,可以跟蹤Django支持的項(xiàng)目中安裝的所有模型,為您的模型提供高級通用接口。
安裝contenttypes框架
contenttypes框架默認(rèn)是被安裝在INSTALLED_APPS中的,
如果刪除了它可以用, django.contrib.contenttypes安裝回來
安裝contenttypes框架通常是個好主意; Django的其他幾個捆綁應(yīng)用程序需要它:
- 管理應(yīng)用程序使用它來記錄通過管理界面添加或更改的每個對象的歷史記錄。
- Django 使用它將用戶權(quán)限綁定到特定模型。
實(shí)現(xiàn)博客系統(tǒng)的點(diǎn)擊量功能
- 首先要創(chuàng)建一個app, 這個app讓它只實(shí)現(xiàn)需要的計(jì)數(shù)功能,這樣符合django設(shè)計(jì)理念
- 我現(xiàn)在想要在我的xadmin里顯示點(diǎn)擊量
models.py
class ReadNum(models.Model):
"""
閱讀次數(shù)統(tǒng)計(jì)
"""
read_num = models.IntegerField(default=0, verbose_name='閱讀次數(shù)')
content_type = models.ForeignKey(ContentType, on_delete=models.DO_NOTHING,
verbose_name="計(jì)數(shù)類型")
object_id = models.PositiveIntegerField(verbose_name='類型id')
contentObject = GenericForeignKey('content_type', 'object_id')
def show_content(self):
return "標(biāo)題: %s" %(self.contentObject.title)
- read_num是我們需要的字段
- 不要忘記遷移文件
類GenericForeignKey
設(shè)置一個有三個部分 GenericForeignKey
- 給你的模型
ForeignKey來設(shè)置ContentType。該字段的通常名稱是“content_type”。 - 為您的模型提供一個字段,該字段可以存儲您要與之相關(guān)的模型中的主鍵值。該字段的通常名稱是“object_id”。
-
GenericForeignKey,傳遞上述兩個字段的名稱。如果這些字段名為“content_type”和“object_id”,則可以省略 - 這些是GenericForeignKey將要查找的默認(rèn)字段名稱 。
models.py
定義一個方法, 用于xadmin顯示點(diǎn)擊量
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="標(biāo)題")
content = UEditorField(verbose_name=u"內(nèi)容", 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="創(chuàng)建日期")
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)

xadmin
- 正常Get read num 字段都是0, 我現(xiàn)在還不會設(shè)置附加字段的名字 和顏色
實(shí)現(xiàn)訪問博客點(diǎn)擊量就增加的功能
- 在創(chuàng)建一個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):
# 閱讀總數(shù) +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):
"""
博客詳細(xì)
: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標(biāo)記
return response
這樣就可以每次看文章的時候點(diǎn)擊量都會加1, 并且設(shè)置了cookie就會讓點(diǎn)擊量更加真實(shí)