ajax在django1.5 ListView中发布数据

时间:2013-03-07 15:07:10

标签: django django-templates django-views

所以,我有一个小博客应用程序(django newbie here)和博客文章,我希望在每个项目中包含一个“评级”(类似于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结合起来 - 但是,不确定是否应该这样。

感谢。

1 个答案:

答案 0 :(得分:2)

通过查看基于类的视图源代码,我无法告诉您我学到了多少。一旦你看到它,就很容易修改你的类对象来做你想做的事情。在您的情况下,如果您向类中添加post方法,则会在映射到视图的网址发布时调用该方法。

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

回复您的评论

由于您希望用户能够从ListView进行upvote / downvote,您需要一些方法来识别被投票到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()