Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I can't tell you how much I learned by looking at the class based view source code. Once you've seen it, it becomes very easy to modify your class object to do what you want. In your case, if you add a <code>post</code> method to your class, it will be called in the event of a post to the url mapped to the view.</p> <pre><code>def post( self, request, *args **kwargs ): # receive the post, process the rating, return your JSON response </code></pre> <p><strong>In response to your comments</strong></p> <p>Since you're wanting users to be able to upvote/downvote from a ListView, you will need some way of identifying the post being voted on to the POST view which handles the request.</p> <p>So if you were to send the id of the blogpost along with the vote, you could grab that model and update it accordingly.</p> <p>assuming a model like this</p> <pre><code>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 ) </code></pre> <p>yourtemplate.html</p> <pre><code>{% for post in object_list %} &lt;div class="blogpost" data-pk="{{post.pk}}"&gt; &lt;span class="score"&gt;{{post.score}}&lt;/span&gt; &lt;a class="upvote" href="#"&gt;Upvote&lt;/a&gt; &lt;a class="downvote" href="#"&gt;Downvote&lt;/a&gt; &lt;/div&gt; {% endfor %} </code></pre> <p>yourjavascript.js</p> <pre><code>$('.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 }); }); </code></pre> <p>views.py</p> <pre><code>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 }) ) </code></pre> <p>To expand further on my last comment, a Rating model might make this easier.</p> <pre><code>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',) </code></pre> <p>Then in your post view</p> <pre><code>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() </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload