2009-10-21 12 views
26

Jestem pewien, że ktoś ma wtyczkę (lub samouczek), która jest podobna do tej, ale mam problem ze znalezieniem: Chcę być w stanie śledzić liczbę "widoków" danego obiektu (tak jak pytanie tutaj na stackoverflow ma "liczbę wyświetleń").Śledź liczbę "odsłon" lub "trafień" obiektu?

Jeśli użytkownik nie jest zalogowany, nie miałbym nic przeciwko próbie umieszczenia pliku cookie (lub zarejestrowania adresu IP), aby nie mógł przypadkowo uruchomić liczby wyświetleń, odświeżając stronę; a jeśli użytkownik jest zalogowany, zezwalaj tylko na jeden "widok" między sesjami/przeglądarkami/adresami IP. Nie sądzę, że potrzebuję tego bardziej od niej.

ja zorientować, że najlepszym sposobem na to jest z Middleware, że jest odłączony od różnych modeli Chcę śledzić i przy użyciu wyrażenia F (swego rodzaju) - Pozostałe pytania dotyczące stackoverlow wspomniałem to (1) (2) (3).

Ale zastanawiam się, czy ten kod istnieje już na wolności - ponieważ nie jestem najbystrzejszym koderem i jestem pewien, że ktoś mógłby zrobić to lepiej. Uśmiech.

Widziałeś to?

Odpowiedz

37

Nie jestem pewien, czy jest w najlepszym guście, aby odpowiedzieć na moje własne pytanie, ale po odrobinie pracy, złożyłem aplikację, która rozwiązuje problemy na serio: django-hitcount.

Możesz przeczytać o tym, jak go używać pod numerem the documentation page.

Pomysły na django-hitcount pochodziły z obu moich dwóch oryginalnych odpowiedzi (Teebes-i-vikingosegundo), które naprawdę sprawiły, że zacząłem myśleć o tym wszystkim.

To jest moja pierwsza próba udostępnienia wtyczce aplikacji społeczności i mam nadzieję, że ktoś inny uzna to za przydatne. Dzięki!

+0

Fajnie, sprawdzę to! – vikingosegundo

+5

Hitcount wydaje się zbyt skomplikowany dla tego zadania. Szczególnie używanie modeli do liczenia trafień może być naprawdę ciężkie. Polecam (podobnie jak w moim projekcie), aby zamiast tego używać Cache. Inteligentne nazwy pamięci podręcznej + limity czasu ładnie radzą sobie z problemem i jest niezwykle szybki. – thedk

+0

świetna aplikacja, dzięki! Czy automatycznie odfiltrowuje trafienia wyszukiwarek? –

8

I odśwież mój pomysł, że ja już napisałem w odpowiedzi na jeden z wymienionych pytań, których nie zrobił podniesionymi uwagi: D

można utworzyć rodzajowego modelu 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') 

w Twój view.py piszesz tę funkcję:

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) 

i widoki, które są zainteresowane w zamian

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

Takie podejście daje moc, a nie tylko liczyć na trafienie, ale do filtrowania HIT-historia przez czas, contenttype i tak dalej ...

Jako hit stolika może być szybko rośnie, powinieneś pomyśleć o strategii usuwania.

Kod niesprawdzone

+0

Yea - I widział swój kod, a wzbudził moją uwagę! Uśmiech. Miałem jednak nadzieję, że coś już znajdę w aplikacji, którą mogę zaimportować, a następnie użyć ... ale mogę spróbować połączyć swój model Hit (i ogólne aspekty) z sugestiami sesji @Teebes. Dzięki. – thornomad

+0

Jasne, powinieneś je połączyć. z sesją dostajesz informacje o pojedynczych użytkownikach. i przy moim podejściu możesz kontrolować uruchamianie widoków bez pisania tego samego kodu w kółko. weź to do rozwiązania. – vikingosegundo

+0

Typo: DateTimeFiles powinien być odczytywany jako DateTimeField, czyż nie? – Meilo

20

Należy użyć Django wbudowany w ramach sesji, to już nie wiele to dla ciebie. I to realizowane w następujący sposób z Q & app gdzie chciałem śledzić widoki:

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

w 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 jest zapewne dlatego, że używanie content-type jest prawdopodobnie rozwiązaniem bardziej nadającym się do ponownego użycia, ale zdecydowanie nie wymyśla koła w kategoriach sesji śledzących, Django już to robi!

Ostatnia rzecz, prawdopodobnie powinieneś mieć widok, który zapisuje trafienie albo przez łącze Ajax lub css, żeby wyszukiwarki nie zwiększały twoich rachunków.

Nadzieję, że pomaga!

+0

To pomaga - w jaki sposób wykorzystałeś informacje o sesji i wszystko będzie przydatne. Ja też lubię podejście Vikingosegundo - które jest bardziej ogólne. Jeśli nie mogę znaleźć niczego innego, mogę połączyć te dwa. I trzeba będzie pamiętać wyszukiwarki - nie myślałem o tym. Ale mogą zawierać pewien nagłówek, który można sprawdzić ... nie? – thornomad

+0

Możesz na pewno sprawdzić nagłówki. to poprzednie pytanie http://stackoverflow.com/questions/45824/counting-number-of-views-for-a-page-ignoring-search-engines ma kilka bardzo dobrych informacji na ten temat (nie dotyczy django). – Teebes

0

Zrobiłem to za pomocą plików cookie. Nie wiem, czy to dobry pomysł, aby to zrobić, czy nie. Poniższy kod najpierw szuka już ustawionego pliku cookie, jeśli istnieje, zwiększa licznik total_view, jeśli go nie ma, zwiększa zarówno total_views, jak i unique_views. Zarówno total_views, jak i unique_views są polem modelu 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

Zrobiłem to, tworząc model PageViews i tworząc w nim kolumnę "Hits". Za każdym razem, gdy trafiony jest adres URL strony głównej. Podnoszę pierwszy i jedyny wiersz kolumny Hit i renderuję go do szablonu. Oto jak to wygląda.

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) 
Powiązane problemy