2009-10-21 17 views
26

Estoy seguro de que alguien tiene una aplicación conectable (o tutorial) que se aproxima a esto, pero tengo problemas para encontrarlo: quiero poder seguir el número de "vistas" que tiene un objeto en particular (como un pregunta aquí en stackoverflow tiene un "recuento de vista").¿Seguir el número de "vistas de página" o "visitas" de un objeto?

Si el usuario no ha iniciado sesión, no me importaría intentar colocar una cookie (o registrar una dirección IP) para que no puedan ejecutar inadvertidamente el recuento de vistas actualizando la página; y si un usuario está conectado, solo les permite una "vista" a través de sesiones/navegadores/direcciones IP. No creo que lo necesite más elegante que eso.

Calculo la mejor manera de hacerlo es con un middleware que se desacopla de los diversos modelos que quiero seguir y utilizando una expresión F (de clases) - otras preguntas sobre stackoverlow han aludido a esto (1) (2) (3).

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

¿Lo has visto?

Respuesta

37

No estoy seguro si es del mejor gusto 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 sobre cómo usarlo en the documentation page.

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

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

+0

¡Bien, lo comprobaré! – vikingosegundo

+5

Hitcount parece demasiado complicado para esta tarea. Especialmente el uso de modelos para contar hits puede ser muy pesado. Yo recomendaría (como lo hice en mi proyecto) usar Caché en su lugar. Los nombres de caché inteligente y los tiempos de espera superan con creces el problema y es extremadamente rápido. – thedk

+0

gran aplicación, gracias! ¿Filtra automáticamente los resultados de los motores de búsqueda? –

8

puedo renovar mi idea, que ya he escrito como una respuesta a una de las cuestiones mencionadas, en las que aún no ha formulado ninguna atención: D

se puede crear un modelo genérico 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') 

en su view.py se escribe 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 interesa a cambio

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

Este enfoque le da el poder, no sólo para contar el golpe, pero para filtrar el hit-historia al tiempo, contenttype y así sucesivamente ...

A medida que el éxito de la tabla podría estar creciendo rápidamente, debes pensar en una estrategia de eliminación.

Código no probado

+0

Sí - Yo vi su código, y tampoco alcé la atención! Sonreír. Sin embargo, esperaba algo que ya estaba en una aplicación que podría importar y luego usar ... pero, puedo intentar y combinar su modelo Hit (y los aspectos genéricos) con las sugerencias de sesión de @Teebes. Gracias. – thornomad

+0

Claro, deberías combinarlos. con la sesión u obtiene la información sobre usuarios únicos. y con mi enfoque puede controlar las vistas que se activarán sin escribir el mismo código una y otra vez. llevar eso a tu solución. – vikingosegundo

+0

Typo: DateTimeFiles debe leer como DateTimeField, ¿no es así? – Meilo

20

Se debe utilizar la django integrado entorno de sesiones, que ya hace mucho de esto para usted. He implementado esto de la siguiente manera con una Q & Una aplicación donde quería realizar un seguimiento de 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()) 

Vikingosegundo es Probablemente, aunque usar content-type es probablemente la solución más reutilizable, pero definitivamente no reinventar la rueda en términos de sesiones de seguimiento, ¡Django ya lo hace!

Última cosa, probablemente debería tener la vista que registra el golpe sea llamada a través de Ajax o un enlace CSS para que los motores de búsqueda no aceleren sus conteos.

Espero que ayude!

+0

Eso ayuda, cómo usaste la información de la sesión y todo te será útil. También me gusta el enfoque de vikingosegundo, que es más genérico. Si no puedo encontrar nada más, puedo combinar los dos. Y tendrá que tener en cuenta los motores de búsqueda, no había pensado en eso. Pero pueden incluir un cierto encabezado, que podría verificarse ... ¿no? – thornomad

+0

Definitivamente puede verificar los encabezados. esta pregunta anterior http://stackoverflow.com/questions/45824/counting-number-of-views-for-a-page-ignoring-search-engines tiene información muy buena sobre esto (no específica de django). – Teebes

0

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_vista, si no está allí, aumenta las vistas total_views y 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 
0

Lo hice creando un modelo de PageViews y haciendo una columna "Hits" en él. Cada vez que se golpea la url de la Página de inicio. Incremento la primera y única fila de columna Hit y la renderizo en la plantilla. Aquí cómo 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) 

Models.py

class PageView(models.Model): 
    hits=models.IntegerField(default=0) 
Cuestiones relacionadas