django 跟踪对象的“页面浏览量”或“点击量”?

bq8i3lrv  于 2023-01-31  发布在  Go
关注(0)|答案(7)|浏览(127)

我相信有人有一个可插入的应用程序(或教程)有接近这一点,但我有麻烦找到它:我希望能够跟踪一个特定对象拥有的“视图”数量(就像stackoverflow上的一个问题有一个“视图计数”)。
如果用户没有登录,我不介意尝试放置一个cookie(或记录一个IP),这样他们就不会因为刷新页面而不经意地增加浏览量;如果一个用户已经登录,只允许他们在会话/浏览器/IP地址之间进行一次“查看”。我不认为我需要比这更花哨的东西。
我认为最好的方法是使用中间件,它与我想要跟踪的各种模型解耦,并使用F表达式(某种程度上)--StackOverflow的其他问题已经暗示了这一点(1),(2),(3)。
但我想知道这段代码是否已经存在了--因为我不是最精明的程序员,我相信有人可以做得更好。
你看过吗?

uxhixvfz

uxhixvfz1#

我不确定回答我自己的问题是否是最好的选择,但经过一番努力,我组装了一个应用程序,认真地解决了这些问题:django-hitcount.
您可以在the documentation page上阅读如何使用它。
django-hitcount的想法来自我最初的两个答案(Teebes和vikingosegundo),这真的让我开始思考整个事情。
这是我第一次尝试与社区分享一个可插入的应用程序,希望其他人发现它有用。谢谢!

vs91vp4v

vs91vp4v2#

你应该使用django内置的session框架,它已经为你做了很多了。我在一个问答应用中用下面的方式实现了这个框架,我想在那里跟踪视图:
在www.example.com中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())

在www.example.com中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链接调用,这样搜索引擎就不会加速你的计数。
希望能有所帮助!

wbrvyc0a

wbrvyc0a3#

您可以创建一个通用的点击模型

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

在www.example.com中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,
        })

这种方法给你的能力,不仅计数命中,但过滤命中历史的时间,内容类型等...
由于命中表可能增长很快,您应该考虑删除策略。

ogq8wdun

ogq8wdun4#

我知道这个问题是一个老问题,而且thornomad已经把一个应用程序来解决这个问题,并启发我与我的解决方案。我想分享这个解决方案,因为我没有找到很多关于这个主题的信息,它可能会帮助别人。我的方法是使一个通用模型可以用于任何基于视图路径(url)的视图。

    • 型号. 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)
    • 查看次数. 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
d8tt03nd

d8tt03nd5#

我通过创建一个模型PageViews并在其中创建一个列"Hits"来实现这一点。每次当Homepage url被点击时。我增加列Hit的第一行也是唯一一行并将其呈现到模板中。

    • 浏览次数. 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)
    • 型号. py**
class PageView(models.Model):
    hits=models.IntegerField(default=0)
jgwigjjp

jgwigjjp6#

我是用cookie做的。不知道这样做是否是个好主意。下面的代码首先寻找一个已经设置好的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
twh00eeo

twh00eeo7#

1.模特设计Post a view显示自己

views = models.IntegerField(default=0)

def update_views(self, *args, **kwargs):
  self.views = self.views + 1
   super(Post, self).save(*args, **kwargs)

发布HTML
1.集装箱altina div克拉辛icine -〉

onload="{{post.update_views}}"

1.标题H1依替酮阿尔蒂纳elave ele

<p class="text-sm mb-5 md:text-base font-normal text-gray-600">
                 {{ post.timestamp}} | Baxıs sayi {{  post.views }} </p>

相关问题