Frage

Ich bin sicher, dass jemand eine steckbare App (oder ein Tutorial) da draußen hat, die sich diesem annähert, aber ich habe Probleme Auf Stackoverflow hat eine "Ansichtsanzahl").

Wenn der Benutzer nicht angemeldet ist, würde es mir nichts ausmachen, ein Cookie (oder eine IP protokollieren) zu platzieren, sodass er die Ansichtsanzahl nicht versehentlich nach oben ausführen kann, indem er die Seite aktualisiert. Und wenn ein Benutzer angemeldet ist, erlauben Sie ihm nur eine "Ansicht" über Sitzungen/Browser/IP -Adressen. Ich glaube nicht, dass ich es schicker brauche.

Ich denke, der beste Weg, dies zu tun, ist mit Middleware, die aus den verschiedenen Modellen entkoppelt ist, die ich verfolgen möchte, und einen F -Ausdruck (von Art) - andere Fragen zu Stackoverlow haben darauf angespielt ((1) (2) (3).

Aber ich frage mich, ob dieser Code bereits in freier Wildbahn vorhanden ist - denn ich bin nicht der versierteste Coder und ich bin sicher, dass jemand es besser machen könnte. Lächeln.

Hast du es gesehen?

War es hilfreich?

Lösung

Ich bin mir nicht sicher, ob es im besten Geschmack ist, meine eigene Frage zu beantworten, aber nach ein wenig Arbeit habe ich eine App zusammengestellt, die die Probleme ernsthaft löst: Django-Hitcount.

Sie können lesen, wie Sie es verwenden können Die Dokumentationsseite.

Die Ideen für Django-Hitcount kamen aus meinen beiden ursprünglichen Antworten (Teebes -und- Vikingosegundo), was mich wirklich dazu gebracht hat, über das Ganze nachzudenken.

Dies ist mein erster Versuch, eine steckbare App mit der Community zu teilen und zu hoffen, dass jemand anderes sie nützlich findet. Vielen Dank!

Andere Tipps

Sie sollten das integrierte Sitzungsrahmen von Django verwenden, es macht bereits viel davon für Sie. Ich habe dies auf folgende Weise mit einer Q & A -App implementiert, in der ich Ansichten verfolgen wollte:

in 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())

in Ansichten.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 hat wahrscheinlich Recht, dass die Verwendung von Content-Typ wahrscheinlich die wiederverwendbarere Lösung ist, aber das Rad in Bezug auf Tracking-Sitzungen definitiv nicht neu erfinden, tut Django das bereits!

Letzteres sollten Sie wahrscheinlich die Ansicht haben, dass die Aufzeichnung des Treffers entweder über AJAX oder einen CSS -Link aufgenommen wird, damit Suchmaschinen Ihre Zählungen nicht verbessern.

Ich hoffe, das hilft!

Sie können ein generisches Hit -Modell erstellen

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

In Ihrer Ansicht.Py Sie diese Funktion schreiben:

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)

und die Ansichten, an denen Sie interessiert sind

return render_to_response_hit_count(request,   'map/list.html',['list',],
        {
            'list': l,
        })

Dieser Ansatz gibt Ihnen die Macht, nicht nur den Treffer zu zählen, sondern auch die Hitgeschichte nach Zeit, ContentType usw. zu filtern ...

Wenn der Treffer schnell wächst, sollten Sie über eine Löschstrategie nachdenken.

Ich weiß, diese Frage ist eine alte und auch Thornomad Hat eine App gestellt, um das Problem zu lösen und mich mit mir zu inspirieren. Ich möchte diese Lösung teilen, da ich nicht viele Informationen zu diesem Thema gefunden habe und es möglicherweise jemand anderem helfen kann. Mein Ansatz ist es, ein generisches Modell zu erstellen, das auf der Grundlage der Ansicht auf der Grundlage des View Path (URL) verwendet werden kann.

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)

Ansichten.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

Ich habe es mit Cookies gemacht. Ich weiß nicht, ob es eine gute Idee ist, das zu tun oder nicht. Der folgende Code sucht nach einem bereits festgelegten Cookie zuerst, wenn er existiert, er erhöht den Total_View -Zähler, wenn es nicht vorhanden ist. Es erhöht sowohl die Total_Views als auch die Unique_Views. Sowohl Total_views als auch Unique_Views sind ein Feld eines Django -Modells.

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

Ich habe dies getan, indem ich ein Modell -Seitenaufruf erstellt und eine Spalte "Hits" erstellt habe. Jedes Mal, wenn die Homepage -URL getroffen wird. Ich erhöht die erste und einzige Zeile von Spalten -Hit und rendere sie in die Vorlage. Hier sieht es aus.

Ansichten.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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top