Pregunta

Estoy seguro de que alguien tiene una aplicación enchufable (o tutorial) que se aproxima a esto, pero tengo problemas para encontrarla: quiero poder rastrear el número de "visitas". un objeto en particular tiene (al igual que una pregunta aquí en stackoverflow tiene un " recuento de vistas ").

Si el usuario no ha iniciado sesión, no me importaría intentar colocar una cookie (o registrar una IP), por lo que no pueden ejecutar involuntariamente el recuento de vistas al actualizar la página; y si un usuario ha iniciado sesión, solo permítales una " vista " A través de sesiones / navegadores / direcciones IP. No creo que lo necesite más que eso.

Me imagino que la mejor manera de hacerlo es con Middleware que está desacoplado de los diversos modelos que quiero rastrear y usando una expresión F (más o menos); otras preguntas en stackoverlow han aludido a esto (1 ) ( 2 ) ( 3 ).

Pero me pregunto si este código ya existe en la naturaleza, porque no soy el programador más sabio y estoy seguro de que alguien podría hacerlo mejor. Sonreír.

¿Lo has visto?

¿Fue útil?

Solución

No estoy seguro de si es mejor responder a mi propia pregunta pero, después de un poco de trabajo, armé una aplicación que resuelve los problemas en serio: django-hitcount .

Puede leer acerca de cómo usarlo en la página de documentación .

Las ideas para django-hitcount vinieron de mis dos respuestas originales ( Teebes -y- vikingosegundo ), lo que realmente me hizo pensar en todo el asunto.

Este es mi primer intento de compartir una aplicación conectable con la comunidad y espero que alguien más lo encuentre útil. Gracias!

Otros consejos

Deberías usar el marco de sesión incorporado de django, ya hace mucho de esto por ti. Implementé esto de la siguiente manera con una aplicación Q & amp; A en la que quería hacer un seguimiento de las vistas:

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

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

Es probable que Vikingosegundo tenga razón, ya que usar el tipo de contenido es probablemente la solución más reutilizable, pero definitivamente no reinventa la rueda en términos de sesiones de seguimiento, ¡Django ya lo hace!

Lo último, probablemente debería tener la vista que registra el hit ya sea a través de Ajax o un enlace CSS para que los motores de búsqueda no aceleren sus conteos.

Espero que ayude!

Podrías crear un modelo de Hit genérico

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

en tu view.py escribes esta función:

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)

y las vistas que le interesan devuelven

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

Este enfoque le da el poder, no solo para contar el golpe, sino también para filtrar el historial de golpes por tiempo, tipo de contenido, etc. ...

Como la tabla de resultados puede estar creciendo rápidamente, debe pensar en una estrategia de eliminación.

Sé que esta pregunta es antigua y también thornomad ha puesto una aplicación para resolver el problema e inspirarme mi solucion Me gustaría compartir esta solución ya que no encontré mucha información sobre este tema y puede ayudar a alguien más. Mi enfoque es hacer que un modelo genérico se pueda usar con cualquier vista basada en la ruta de la vista (url).

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

Lo hice usando cookies. No sé si es una buena idea hacer eso o no. El siguiente código busca una cookie ya establecida primero, si existe, aumenta el contador total_view. Si no está allí, aumenta tanto total_views como unique_views. Tanto total_views como unique_views son un campo de un modelo de 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

Hice esto creando un modelo de PageViews y haciendo una columna " Hits " en eso. Cada vez que se golpea la URL de la página principal Incremento la primera y única fila de la columna Hit y la represento en la plantilla. Así es como se ve.

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)

Modelos.py

class PageView(models.Model):
    hits=models.IntegerField(default=0)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top