1

だから、私はブログ記事を含む小さなブログアプリ(ここではdjango初心者)を持っており、これらの各項目に「評価」を含めようとしています(stackoflowのアップ/ダウンに似ています)。だから、私が持っているのは ListView の ajax ベースの GET ですが、この評価データを「変更」するには POST が必要であることに気付きました。django ListView からデータを投稿しようとしましたが、これを行う方法がわかりません。すべてのブログ記事 (ページ付けされた) のリストビューである現在の GET コードは次のようになります。

#views.py
class AwesomeDisplayListView(JSONResponseMixin,ListView):
    model = blogposts
    template_name = "awesome_list.html"
    paginate_by = '15'
    context_object_name = "searchres"

    def get_context_data(self, **kwargs):
        print "this is get_context_data"
        context = super(SearchDisplayListView, self).get_context_data(**kwargs)
        q = self.request.GET.get('q')
        context['searchq'] = q
        return context

    def get_queryset(self):
        print "this is get_queryset"
                # get some queryset
        return queryset 

    def render_to_response(self, context):
        if self.request.is_ajax():
            obj = {'name':'ajax', 'birthday':'may'}
            return JSONResponseMixin.render_to_response(self, obj)
        else:
            return ListView.render_to_response(self, context)

上記のコードは、テンプレートにデータ (「obj」) を取得するのにうまく機能し、ブログ投稿と GET ajax の両方をレンダリングできますが、次のようにデータを投稿したいと考えています: [1] 評価は現在の値から 1 増加 [2] 特定のアクション (クリックして投票) には、login_required が必要です。

誰かがこれを行うために正しい方向に私を向けることができるかどうか疑問に思っていました. 私は問題をグーグルで検索しましたが、Mixins を組み合わせることを提案しているようですが、これが当てはまるかどうかはわかりません。

ありがとう。

4

1 に答える 1

2

クラスベースのビューのソースコードを見て、どれだけ学んだかはわかりません。一度見たら、クラスオブジェクトを変更して自分のやりたいことをするのはとても簡単になります。あなたの場合、postクラスにメソッドを追加すると、ビューにマップされたURLへの投稿のイベントで呼び出されます。

def post( self, request, *args **kwargs ):
  # receive the post, process the rating, return your JSON response

あなたのコメントに応えて

ユーザーがListViewから賛成/反対投票できるようにしたいので、リクエストを処理するPOSTビューに投票されている投稿を識別する何らかの方法が必要になります。

したがって、投票と一緒にブログ投稿のIDを送信する場合は、そのモデルを取得して、それに応じて更新することができます。

このようなモデルを想定

class BlogPost( models.Model ):
  upvotes=models.IntegerField( default=0 )
  downvotes=models.IntegerField( default=0 )

  def get_score( self ):
    return self.upvotes - self.downvotes

  score=property( get_score )

yourtemplate.html

{% for post in object_list %}
 <div class="blogpost" data-pk="{{post.pk}}">
  <span class="score">{{post.score}}</span>
  <a class="upvote" href="#">Upvote</a>
  <a class="downvote" href="#">Downvote</a>
 </div>
{% endfor %}

yourjavascript.js

$('.blogpost').on( 'click', '.upvote,.downvote', function( e ){
  e.preventDefault();
  var id=$( this ).closest('.blogpost').data('pk'),
  upvote=$( this ).is('.upvote'),
  xhr=$.ajax({
    url: location.href, 
    type: 'post',
    data:{ id: id, upvote: upvote ? 1 : 0 },
    dataType: 'json'
  });
  xhr.done( function( data ){
     // successful submission
  });
});

views.py

class AwesomeDisplayListView(JSONResponseMixin,ListView):
  model = BlogPost
  template_name = "awesome_list.html"
  paginate_by = '15'
  context_object_name = "searchres" 

  def post( self, request, *args, **kwargs ):
    id=request.POST.get('id')
    upvote=int( request.POST.get('upvote') )
    blogpost=BlogPost.objects.get( pk=id )
    if upvote:
      blogpost.upvotes=blogpost.upvotes + 1
    else:
      blogpost.downvotes=blogpost.downvotes + 1
    blogpost.save()
    return http.HttpResponse( json.dumps({ 'score': blogpost.score }) )

私の最後のコメントをさらに拡張するために、評価モデルはこれをより簡単にするかもしれません。

class BlogPost( models.Model ):
  title=models.CharField( max_length=100 )
  def get_score( self ):
    return self.ratings.filter( up=True ).count() - self.ratings.filter( up=False ).count()

  score=property( get_score )


class Rating( models.Model ):
  blogpost=models.ForeignKey( BlogPost, related_name="ratings" )
  user=models.ForeignKey( User )
  up=models.BooleanField( default=True )

  class Meta:
    unique_together=('blogpost','user',)

次に、投稿ビューで

def post( self, request, *args, **kwargs ):
  id=request.POST.get('id')
  upvote=bool( int( request.POST.get('upvote') ) )
  blogpost=BlogPost.objects.get( pk=id )
  rating, is_new=Rating.objects.get_or_create( user=request.user, blogpost=blogpost )
  if rating.up != upvote:
    rating.up=upvote
    rating.save()
于 2013-03-07T16:26:45.723 に答える