2013-03-07 69 views
1

因此,我有一個博客文章的小博客應用程序(django newbie),並且我希望對這些項目中的每一項都包含一個「評級」(類似於上/下stackoflow)。所以,我有一個基於Ajax的ListView中的GET - 但我現在意識到我需要POST來修改這個評級數據。我一直在尋找從django ListView發佈數據,但我無法看到如何做到這一點。目前獲取代碼,這是所有博客文章的列表視圖(分頁),如下所示:ajax在django1.5中發佈數據ListView

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

上面的代碼工作正常,獲取的數據(「目標文件」)到模板,我能夠呈現兩種blogposts和GET ajax,但是,我想要做的是發佈數據,以便: [1]該評級從當前值增加1 [2]特定操作(點擊投票),要求login_required 。

我想知道如果有人能指出我在正確的方向做到這一點。我搜索了這個問題,人們似乎建議將Mixins結合起來 - 但不確定是否應該這樣。

謝謝。

回答

2

我無法通過查看基於類的視圖源代碼告訴你我學到了多少東西。一旦你看到它,就很容易修改你的類對象來做你想做的事情。在你的情況下,如果你爲你的課程增加了一個post方法,它將在映射到視圖的url發佈後被調用。

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

在回答您的意見

既然你希望用戶能夠從一個ListView給予好評/ downvote,你需要確定該職位的某種方式被表決的POST處理請求的視圖。

因此,如果您要將blogpost的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() 
+0

起初,我也想起來了 - 但是,從看:http://ccbv.co.uk/projects/Django/1.5/django。 views.generic.list/ListView /我看不到def post - 所以我的印象是ListView中不允許這樣做。情況不是這樣嗎? – JohnJ 2013-03-07 16:35:41

+0

任何事情都是允許的。這只是一個簡單的課程。看看調度方法。如果你創建了一個匹配'http_method_names'中名字的方法,它將被調用。 – czarchaic 2013-03-07 17:07:27

+0

我仍然不確定如何使用帖子..我真的沒有在這裏的形式:(我想通過ajax發佈和更新..你有任何機會的例子嗎?再次感謝 – JohnJ 2013-03-07 17:47:52