我确信有人有一个可插入的应用程序(或教程)与此类似,但我很难找到它:我希望能够跟踪特定对象的“视图”数量(就像 stackoverflow 上的一个问题有“视图计数”一样)。

如果用户没有登录,我不介意尝试放置 cookie(或记录 IP),这样他们就不会因刷新页面而无意中增加浏览次数;如果用户已登录,则仅允许他们跨会话/浏览器/IP 地址进行一次“查看”。我认为我不需要比这更奇特的东西了。

我认为最好的方法是使用与我想要跟踪的各种模型分离的中间件,并使用 F 表达式(某种) - stackoverlow 上的其他问题已经提到了这一点(1) (2) (3).

但我想知道这段代码是否已经存在——因为我不是最精明的编码员,而且我确信有人可以做得更好。微笑。

你有看到它吗?

有帮助吗?

解决方案

我不确定它是否最适合回答我自己的问题但是,经过一些工作后,我整理了一个能够认真解决问题的应用程序: django-hitcount

您可以在文档页面上阅读有关如何使用它的信息。

django-hitcount的想法来自我的两个原始答案( Teebes - 和 - vikingosegundo ),这让我开始思考整件事。

这是我第一次尝试与社区共享可插拔应用程序,并希望其他人发现它有用。谢谢!

其他提示

您应该使用 django 内置会话框架,它已经为您完成了很多工作。我通过一个问答应用程序通过以下方式实现了这一点,我想在其中跟踪视图:

在模型.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 链接调用记录点击的视图,以便搜索引擎不会加快您的计数。

希望有帮助!

您可以创建通用的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,
        })

这种方法不仅可以计算命中数,还可以按时间,内容类型等过滤命中历史记录...

由于命中表可能会快速增长,您应该考虑删除策略。

我知道这个问题很旧,并且 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

我是用饼干做的。不知道这样做是否是个好主意。以下代码首先查找已设置的cookie,如果它存在则会增加total_view计数器,如果它不存在则会增加total_views和unique_views。 total_views和unique_views都是Django模型的字段。

def view(request):
    ...
    cookie_state = request.COOKIES.get('viewed_post_%s' % post_name_slug)
    response = render_to_response('community/post.html',context_instance=RequestContext(request, context_dict))
    if cookie_state:
        Post.objects.filter(id=post.id).update(total_views=F('total_views') + 1)
    else:
        Post.objects.filter(id=post.id).update(unique_views=F('unique_views') + 1)
        Post.objects.filter(id=post.id).update(total_views=F('total_views') + 1)
                        response.set_cookie('viewed_post_%s' % post_name_slug , True, max_age=2678400)
    return response

我是通过创建一个模型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)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top