我确信有人在那里有一个可插拔的应用程序(或教程)近似于此,但我找不到它:我希望能够跟踪特定对象的“视图”数量(就像stackoverflow上的一个问题有一个“查看计数”)。
如果用户未登录,我不介意尝试放置cookie(或记录IP),这样他们就不会无意中通过刷新页面来提高视图数量;如果用户已登录,则只允许他们跨会话/浏览器/ IP地址进行一次“查看”。我认为我不需要任何比这更好的东西。
我认为最好的方法是使用与我想要跟踪的各种模型分离并使用F表达式(各种类型)的中间件 - 其他关于stackoverlow的问题已提到这一点(1 )(2)(3)。
但是我想知道这个代码是否已经存在于野外 - 因为我不是最精明的编码器,我相信有人可以做得更好。微笑。
你见过吗?
答案 0 :(得分:44)
我不确定回答我自己的问题是否最好,但经过一些工作后,我整理了一个能够认真解决问题的应用程序:django-hitcount。
您可以在the documentation page了解如何使用它。
django-hitcount的想法来自我的两个原始答案(Teebes - 和 - vikingosegundo),这让我开始思考整个问题。
这是我第一次尝试与社区共享可插拔应用程序,并希望其他人发现它有用。谢谢!
答案 1 :(得分:22)
你应该使用django内置的会话框架,它已经为你做了很多这样的事情。我通过以下方式使用Q& A应用程序实现了这一点,我想跟踪视图:
在models.py中:
class QuestionView(models.Model):
question = models.ForeignKey(Question, related_name='questionviews')
ip = models.CharField(max_length=40)
session = models.CharField(max_length=40)
created = models.DateTimeField(default=datetime.datetime.now())
在views.py中:
def record_view(request, question_id):
question = get_object_or_404(Question, pk=question_id)
if not QuestionView.objects.filter(
question=question,
session=request.session.session_key):
view = QuestionView(question=question,
ip=request.META['REMOTE_ADDR'],
created=datetime.datetime.now(),
session=request.session.session_key)
view.save()
return HttpResponse(u"%s" % QuestionView.objects.filter(question=question).count())
Vikingosegundo可能是正确的虽然使用内容类型可能是更可重用的解决方案,但绝对不会在跟踪会话方面重新发明轮子,Django已经这样做了!
最后,您可能应该通过Ajax或css链接调用记录命中的视图,以便搜索引擎不会增加您的计数。
希望有所帮助!
答案 2 :(得分:9)
您可以创建通用的Hit模型
class Hit(models.Model):
date = models.DateTimeField(auto_now=True)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
在你的view.py中你写这个函数:
def render_to_response_hit_count(request,template_path,keys,response):
for key in keys:
for i in response[key]:
Hit(content_object=i).save()
return render_to_response(template_path, response)
以及您有兴趣返回的观点
return render_to_response_hit_count(request, 'map/list.html',['list',],
{
'list': l,
})
这种方法不仅可以计算命中数,还可以按时间,内容类型等来过滤命中历史记录...
由于命中表可能会快速增长,您应该考虑删除策略。
答案 3 :(得分:2)
我知道这个问题是个老问题,thornomad也发布了一个应用程序来解决问题并启发我解决方案。我想分享此解决方案,因为我没有找到太多有关此主题的信息,它可能会对其他人有所帮助。 我的方法是基于视图路径(URL)使通用模型可用于任何视图。
models.py
class UrlHit(models.Model):
url = models.URLField()
hits = models.PositiveIntegerField(default=0)
def __str__(self):
return str(self.url)
def increase(self):
self.hits += 1
self.save()
class HitCount(models.Model):
url_hit = models.ForeignKey(UrlHit, editable=False, on_delete=models.CASCADE)
ip = models.CharField(max_length=40)
session = models.CharField(max_length=40)
date = models.DateTimeField(auto_now=True)
views.py
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
def hit_count(request):
if not request.session.session_key:
request.session.save()
s_key = request.session.session_key
ip = get_client_ip(request)
url, url_created = UrlHit.objects.get_or_create(url=request.path)
if url_created:
track, created = HitCount.objects.get_or_create(url_hit=url, ip=ip, session=s_key)
if created:
url.increase()
request.session[ip] = ip
request.session[request.path] = request.path
else:
if ip and request.path not in request.session:
track, created = HitCount.objects.get_or_create(url_hit=url, ip=ip, session=s_key)
if created:
url.increase()
request.session[ip] = ip
request.session[request.path] = request.path
return url.hits
答案 4 :(得分:1)
我是用饼干做的。不知道这样做是否是个好主意。以下代码首先查找已设置的cookie,如果它存在则会增加total_view计数器,如果它不存在则会增加total_views和unique_views。 total_views和unique_views都是Django模型的字段。
C <= B
答案 5 :(得分:0)
我是通过创建一个模型PageViews并在其中创建一个“Hits”列来实现的。每当主页网址被点击时。我增加列的第一行和唯一一行并将其渲染到模板。这是它的外观。
<强> Views.py 强>
def Home(request):
if(PageView.objects.count()<=0):
x=PageView.objects.create()
x.save()
else:
x=PageView.objects.all()[0]
x.hits=x.hits+1
x.save()
context={'page':x.hits}
return render(request,'home.html',context=context)
的 Models.py 强>
class PageView(models.Model):
hits=models.IntegerField(default=0)