2009-10-21 12 views
26

Sono sicuro che qualcuno abbia un'app (o un'esercitazione) collegabile che si avvicina a questo, ma ho difficoltà a trovarlo: voglio essere in grado di tenere traccia del numero di "viste" che un oggetto particolare ha (proprio come un la domanda qui su stackoverflow ha un "conteggio delle visualizzazioni").Tieni traccia del numero di "visualizzazioni di pagina" o "accessi" di un oggetto?

Se l'utente non ha effettuato l'accesso, non mi dispiacerebbe tentare di inserire un cookie (o registrare un IP) in modo che non possano inavvertitamente eseguire il conteggio delle visualizzazioni aggiornando la pagina; e se un utente ha effettuato l'accesso, consente loro solo una "visualizzazione" tra sessioni/browser/indirizzi IP. Non penso di aver bisogno di più.

immagino il modo migliore per farlo è con Middleware che viene disaccoppiato dai vari modelli che voglio tracciare e utilizzando un'espressione F (specie di) - altre domande sul stackoverlow hanno accennato a questo (1) (2) (3).

Ma mi chiedo se questo codice esista già in natura - perché non sono il codificatore più esperto e sono sicuro che qualcuno potrebbe farlo meglio. Sorriso.

Hai visto?

risposta

37

Non sono sicuro che sia il modo migliore per rispondere alla mia domanda ma, dopo un po 'di lavoro, ho creato un'app che risolve i problemi sul serio: django-hitcount.

È possibile leggere come utilizzarlo su the documentation page.

Le idee per django-hitcount sono venute da entrambe le mie due risposte originali (Teebes e vikingosegundo), che mi hanno davvero fatto riflettere sull'intera cosa.

Questo è il mio primo tentativo di condividere un'app collegabile con la comunità e sperare che qualcun altro lo trovi utile. Grazie!

+0

Bello, lo controllerò! – vikingosegundo

+5

Hitcount sembra complicato per questo compito. Soprattutto usare i modelli per contare i colpi può essere molto pesante. Vorrei raccomandare (come ho fatto nel mio progetto) di usare Cache invece. I nomi delle smart cache + i timeout hanno problemi con i problemi ed è estremamente veloce. – thedk

+0

ottima app, grazie! Filtra automaticamente i risultati dei motori di ricerca? –

8

ho ripubblicare la mia idea, che ho già scritto come una risposta a una delle domande sopra, dove che non ha ancora sollevato alcuna attenzione: D

è possibile creare un modello di Hit generica

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 il vostro view.py si scrive questa funzione:

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) 

e la vista che si sono interessati in cambio

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

Questo approccio si dà il potere, non solo di contare il colpo, ma per filtrare il colpo-storia dal tempo, contenttype e così via ...

Come la hit-tabella potrebbe essere in rapida crescita, dovresti pensare a una strategia di cancellazione.

codice non testato

+0

Sì - ho visto il tuo codice, e mi alzo la mia attenzione! Sorriso. Tuttavia, speravo in qualcosa che già potevo importare e poi usare ... ma potrei provare a combinare il tuo modello Hit (e gli aspetti generici) con i suggerimenti di sessione di @Teebes. Grazie. – thornomad

+0

Certo, dovresti combinarli. con la sessione ottieni le informazioni sui singoli utenti. e con il mio approccio puoi controllare le visualizzazioni da attivare senza scrivere lo stesso codice più e più volte. prendi quello per la tua soluzione. – vikingosegundo

+0

Typo: DateTimeFiles dovrebbe essere letto come DateTimeField, non dovrebbe? – Meilo

20

Si dovrebbe usare il Django incorporato quadro della sessione, lo fa già un sacco di questo per voi. Ho implementato questo nel modo seguente con un Q & Un app dove volevo tenere traccia vista:

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 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 è probabilmente è giusto che usare il content-type sia probabilmente la soluzione più riutilizzabile ma sicuramente non reinventare la ruota in termini di sessioni di tracking, Django lo fa già!

Ultima cosa, probabilmente dovresti avere la vista che registra l'hit sia chiamato tramite Ajax o un link css in modo che i motori di ricerca non aumentino i tuoi conteggi.

Spero che questo aiuti!

+0

Questo aiuta - come hai usato le informazioni sulla sessione e tutto sarà utile. Mi piace anche l'approccio di vikingosegundo, che è più generico. Se non riesco a trovare altro, posso combinare i due. E, dovrò tenere a mente i motori di ricerca - non ci avevo pensato. Ma potrebbero includere una determinata intestazione, che potrebbe essere controllata ... no? – thornomad

+0

Puoi sicuramente controllare le intestazioni. questa domanda precedente http://stackoverflow.com/questions/45824/counting-number-of-views-for-a-page-ignoring-search-engines ha alcune ottime informazioni su questo (non specifico django). – Teebes

0

L'ho fatto usando i cookie. Non so se sia una buona idea farlo o meno. Il seguente codice cerca un cookie già impostato per primo se esiste, aumenta il contatore total_view se non è lì, aumenta sia total_views che unique_views. Sia total_views che unique_views sono un campo di un modello 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

Ho fatto questo creando un modello PageViews e creando una colonna "Hits" al suo interno. Ogni volta che viene colpito l'url della home page. Incremento la prima e sola riga della colonna Hit e la renderò al modello. Ecco come appare.

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) 
Problemi correlati