所以,我有一个小博客应用程序(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结合起来 - 但是,不确定是否应该这样。
感谢。
答案 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()