2009-10-21 22 views
26

私は誰かがこれを近似するプラグイン可能なアプリケーション(またはチュートリアル)を持っていると確信していますが、私はそれを見つけるのが難しいです:特定のオブジェクトが持つ「ビュー」の数を追跡できるようにしたいここでのstackoverflowの質問には「ビュー数」があります)。オブジェクトの「ページビュー数」または「ヒット数」を追跡しますか?

ユーザーがログインしていない場合は、ページを更新して誤って表示回数を上げることができないように、Cookieを置く(またはIPをログに記録する)ことはできます。ユーザーがログインしている場合は、セッション/ブラウザー/ IPアドレス全体で1つの「ビュー」を許可するだけです。私はそれよりも好きではないと思う。

私はこれを行うための最善の方法は、私が追跡する様々なモデルから分離し、(種類の)F式を使用しているミドルウェアである把握 - stackoverlow上の他の質問は、これに(1)をほのめかしている(2 )(3)。

しかし、私はこのコードが野生の中にすでに存在しているのだろうか - 私は精巧なコーダーではないので、誰かがそれをより良くすることができると確信しているからだ。スマイル。

あなたはそれを見ましたか?

答えて

37

自分の質問に答えるのが最善の味であるかどうかはわかりませんが、少しの作業の後で、本物の問題を解決するアプリをまとめました:django-hitcount

the documentation pageでの使用方法を読むことができます。

django-hitcountのアイデアは、私の2つの元の回答(Teebes -and- vikingosegundo)の両方から得られたもので、実際に私はすべてを考え始めました。

これは私のコミュニティでプラグイン可能なアプリを共有しようとする私の最初の試みで、誰かがそれが有用だと願っています。ありがとう!

+0

ニース、私はそれをチェックします! – vikingosegundo

+5

ヒットカウントはこのタスクでは複雑すぎるようです。ヒット数をカウントするモデルを使用すると、特に重いことがあります。私は代わりにキャッシュを使用するように(私のプロジェクトで行ったように)お勧めします。スマートキャッシュ名+タイムアウトは問題をうまく処理しており、非常に高速です。 – thedk

+0

すばらしいアプリ、ありがとう!それは自動的に検索エンジンのヒットをフィルタリングしますか? –

8

私はすでにそれが注意を提起didntの言及した質問の一つの答えとして書いたことを、私の考えを再投稿:D

あなたがで

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

一般的なヒットモデルを作成することができますあなたのview.pyあなたはこの関数を書く:

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) 

、あなたがリターン

に興味のある景色
return render_to_response_hit_count(request, 'map/list.html',['list',], 
     { 
      'list': l, 
     }) 

このアプローチは、ヒットをカウントするために、しかし、時間によってヒット歴史をフィルタリングのcontentTypeのように...ヒットテーブルとして

が急速に成長する可能性があるだけでなく、あなたに力を与えます削除戦略について考えるべきです。

コードテストされていない

+0

いや - 私はあなたのコードを見なかったし、それは私の注意を上げました!スマイル。しかし、私はちょうどインポートして使用することができるアプリ内の何かを期待していました...しかし、私はあなたのヒットモデル(および一般的な側面)を@Teebesのセッション提案と組み合わせてみることができます。ありがとう。 – thornomad

+0

確かに、それらを組み合わせるべきです。セッションでは、単一のユーザーに関する情報を取得します。私のアプローチでは、同じコードを何度も何度も何度も書かずに、ビューをトリガするように制御できます。解決策にそれを取る。 – vikingosegundo

+0

Typo:DateTimeFilesは、DateTimeFieldとして読み込む必要がありますか? – Meilo

20

あなたはそれがすでにあなたのためにこれの多くを行い、内蔵のセッションフレームワークジャンゴを使用する必要があります。 views.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()) 

models.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がある私は、Q &私はビューを追跡したかったアプリで、次の方法でこれを実装しましたコンテンツタイプを使用する方がおそらく再利用可能なソリューションですが、セッションを追跡するという観点から見れば、Djangoはすでにそうしています。

最後に、検索エンジンがカウントを更新しないように、ヒットを記録するビューをAjaxまたはCSSリンク経由で呼び出す必要があります。

希望に役立ちます!

+0

これは役に立ちます - どのようにセッション情報を使用したのか、そしてすべてが役に立つでしょう。 vikingosegundoのアプローチも好きです。これはより一般的です。私が他の何かを見つけることができない場合、私は2つを組み合わせることができます。そして、検索エンジンを念頭に置いておく必要があります - 私はそれを考えていませんでした。しかし、彼らは確認することができる特定のヘッダーを含めることがあります...いいえ? – thornomad

+0

ヘッダーを確かに確認できます。この以前の質問http://stackoverflow.com/questions/45824/counting-number-of-views-for-a-page-ignoring-search-enginesこれに関するいくつかの非常に良い情報を持っています(非ジャンゴ固有)。 – Teebes

0

私はクッキーを使用しました。そうするかしないかは分かりません。次のコードでは、既に設定されているクッキーを最初に探します。クッキーが存在しない場合はtotal_viewカウンターを増加させ、存在しない場合はtotal_viewsとunique_viewsの両方を増加させます。 total_viewsとunique_viewsは両方とも、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

これは、モデルPageViewsを作成し、その中に「ヒット」という列を作成することで行いました。ホームページのURLがヒットするたびに。私は列ヒットの最初と唯一の行をインクリメントし、それをテンプレートにレンダリングします。ここでそれはどのように見える。

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) 
関連する問題