代码之家  ›  专栏  ›  技术社区  ›  thornomad

跟踪对象的“页面浏览”或“点击”次数?

  •  32
  • thornomad  · 技术社区  · 15 年前

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

    我认为实现这一点的最佳方法是使用中间件,该中间件与我想要跟踪的各种模型分离,并使用F表达式(某种形式)——关于StackOverflow的其他问题也提到了这一点( 1 2 ), ( 3 ).

    你看到了吗?

    6 回复  |  直到 4 年前
        1
  •  53
  •   Community Jaime Torres    7 年前

    django-hitcount .

    the documentation page .

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

        2
  •  29
  •   Teebes    15 年前

    您应该使用django内置会话框架,它已经为您做了很多这方面的工作。我以以下方式通过一个Q&我想在其中跟踪视图的应用程序:

    在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已经做到了!

    希望有帮助!

        3
  •  14
  •   vikingosegundo    4 年前

    你可以创建一个通用的命中模型

    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')
    

    在your 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,
            })
    

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

        4
  •  9
  •   Radico    6 年前

    我知道这是一个老问题,而且 thornomad

    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)
    

    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
    
        5
  •  5
  •   Pankaj Mishra    7 年前

    为此,我创建了一个模型页面视图,并在其中创建了一个“点击”栏。每次点击主页url时。我增加列Hit的第一行也是唯一一行,并将其渲染到模板。这是它的样子。

    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)
    
        6
  •  3
  •   Mudit Jain    8 年前

    我是用饼干做的。我不知道这样做是不是个好主意。下面的代码首先查找已设置的cookie,如果它存在,则增加total_view计数器,如果它不存在,则增加total_view和unique_view。total_视图和unique_视图都是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