From e58a3be5e847fc506ac0c56a7f407b03281af5ad Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Thu, 11 Oct 2018 12:16:57 +0200 Subject: [PATCH] Added voting. --- backend/db.sqlite3 | Bin 77824 -> 78848 bytes backend/postings/api/views.py | 10 +++----- .../0004_remove_reviewhelpfulvote_user.py | 17 +++++++++++++ backend/postings/models.py | 12 ++++----- backend/postings/static/postings/js/voting.js | 23 ++++++++++++++++++ .../templates/postings/frontend/review.html | 10 ++++---- 6 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 backend/postings/migrations/0004_remove_reviewhelpfulvote_user.py diff --git a/backend/db.sqlite3 b/backend/db.sqlite3 index b64c046c45f42ed64f0ba4a890c19be9de0c6ee5..91e430b96410eec80e276b9062d8d29e416670bc 100644 GIT binary patch delta 2511 zcmai$e{2&~9KheZ?={=ly0#npLHV`7kbyAn-H-OV1+=B3Y^;O9y4jM56bh`{=veog zm?F#s{R72AXJSkMjhd*5uEIqB7>bC2#2-a){7AG)8EtqRSnecMDYS>V*swncCX-bmWS3dmX$ zpch@6lVcDPv)Y8Sa6vdh|2ZxgXJ-v!yHTCH6&D)Ax%XJiQ$n<$7~I&9uG?`z^2gkl z7H?VKF2&c@hw2)MudcjneV?yMso&Umuin$@)?2naH`Ru8PkU{=E*k5s_wDxVa@5B? zQgbl2T9$~ul1M8FDU)1PinB^`Ryrhys>;dnRpr)20Fwy*hTmZl&ZOUIu8+f}Ej+i> zQ~UU_o3olz<6OnLjB_#Pe9jVN0*q%BaN0PnBVJKmZifhhOE3nX!Fk$v5?+Uw;RHMf zPs0=N7#xC!p%3;!8$^=UekX+3t)iWC4reK631=~95$9~qLQdYS$eR_d{ECG$pVQ2l zmmJ$)BkFcYAovIVgx}z2xC-CFH}Exl0iVD{n%`M?7f!>Q@EXnWBs>q#f&oWpmP3%B zU9=W9h>(Nr409Mt8A=$68HyNYGZZouFxVKZ3>Job1~WsRaq*BNpA{2^o2&~7+)Uca ze*r*C%qI_LFJhHqMqxy&ED8&SFNGsQ4ZeX-;~3V^Bzgsf4V!p>!fVb!Zkx}HbMPH? zK%^?kQ6=k@4woVkji{R=y{(bH^^x|@T|Mp1vF=D&EF6vO=q{@u>M{|$c^NI5=2V?d zqD{A0Zfi8EsmV3=JzAQ~e)NVga!g#Yz>J0vyaU}(DO?p^6dn@h;ji#9yb0%_kI)d! zKb-K`Y0H+H^!d9g9Zp@*U1WO0x7(%7dgf$yNRsZ-8^qR7sfd&J2cg&7?rp=d4#(Px(EOj3|hBB@T5Xs($ZF6!{wsAKwjl9+l?Tsj?K zok%lVh{QD3w3^!%qH2mtGSw?#7R!_+k@l_CWe3q{#bro_m8>^^N|V;&)LfdRk_=W<|G()j)iCWJH8)^$pXnv!+ zGZyb|-Mc$3Ns_v)E7B3`jnKfRsy(Txs+Uex+j`=Wt~(|-`jM0MDoL(%(lVAEM)9r5 zYyl4;;e9+r?fv+{gVln`KV)+E#?+nRUETeXG}uS>l8!xnQP*C*GZOBJ@7&(6IQ+iA zK!YzRH$)rdVAHyeP;>`r=x9_LqJaT_i(hN-1^WHo&8?wmP~F%P(EK#|qr+u@yR?wE zu01&D?rRuq@1Xbh1)Dr=4IMT8p{702P)k7d5AJLWb@&H^EddhpQkPsi5E{M!c&T01 z?)XrS#4E}+Ydsm`0;urNB2ix-wzgt zI1QH$DaQ4!6Ew7l>l z!gZqWrYnUmstf7Mw5t`VkQMr)tU$unA_)=-M4_T)x4da!80J0CdFRYKu)+qG*hq%S zPY9_Ndvk@txgLX`*uG6`aFV3pL^x={37k+(Y!@0z>jkHYv-^&!5j@5;a~PyEqButR zOmaU+yjVI8+qfd_F>c-TBxGkQ`t*v)0qN>z>DI0~zu$EvP}bFV_*|ge>Tl@kX~+rr z%7Z=bs;1gQwFhf@`z!l{4ZVRDPitBCsgASlZT%;!s|&hI+)h`a&E>Q?-LlJ5oC$sqEvglr2I)FcNwd=D{dtqmVpUSg$j;`e3k0aoIsO_H?&*HJ@&4 zc6$q*-uygQB4XIhN9N6n-3D4kc7SAV{vWf*0l#cXz($LlW%*aPWDl0sDSPb@N$RZC znSDMO>fk5VwkKTvTD$oE+h!%*0Vbv10eAStOWC~SO%gY*=Zwaq-(UuYY4PZ9U?Zl9 zskO+{ey?hQ&JsE+?$cC%xfnDxLmHp5qyu^C3x#yh0xl9<6!n*=Eb1Uj2r+^&A-u(@ em;{+}A`h}aXa)qy0ynX_sfApq0JU-L6Z`=iZOfkk diff --git a/backend/postings/api/views.py b/backend/postings/api/views.py index e8c228b..c21d82f 100644 --- a/backend/postings/api/views.py +++ b/backend/postings/api/views.py @@ -2,6 +2,7 @@ from rest_framework import generics, mixins from postings.models import * from .serializers import * from django.db.models import Q +from django.http import * # The view for listing all generic Review objects. @@ -14,13 +15,6 @@ class ReviewView(generics.RetrieveUpdateDestroyAPIView): queryset = Review.objects.all() serializer_class = ReviewSerializer -class ReviewHelpfulVote(mixins.CreateModelMixin): - lookup_field = 'pk' - serializer_class = ReviewHelpfulVoteSerializer - - def post(self, request, *args, **kwargs): - return self.create(request, *args, **kwargs) - def review_helpful_vote(request, review_id): if request.method == 'POST': helpful = request.POST.get('helpful') @@ -38,4 +32,6 @@ def review_helpful_vote(request, review_id): helpful=helpful ) + return HttpResponse(status=201) + return HttpResponseBadRequest("Bad Request") \ No newline at end of file diff --git a/backend/postings/migrations/0004_remove_reviewhelpfulvote_user.py b/backend/postings/migrations/0004_remove_reviewhelpfulvote_user.py new file mode 100644 index 0000000..2f1223a --- /dev/null +++ b/backend/postings/migrations/0004_remove_reviewhelpfulvote_user.py @@ -0,0 +1,17 @@ +# Generated by Django 2.1.1 on 2018-10-11 09:27 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('postings', '0003_auto_20181002_1355'), + ] + + operations = [ + migrations.RemoveField( + model_name='reviewhelpfulvote', + name='user', + ), + ] diff --git a/backend/postings/models.py b/backend/postings/models.py index d660248..cf9fd89 100644 --- a/backend/postings/models.py +++ b/backend/postings/models.py @@ -62,12 +62,14 @@ class Review(models.Model): author = models.ForeignKey('postings.User', on_delete=models.PROTECT, null=True, blank=True) # Gets the total number of votes which marked this review as 'helpful'. - def getHelpfulVoteCount(self): - return ReviewHelpfulVote.objects.filter(pk=self.pk, helpful=True).count() + @property + def helpful_vote_count(self): + return ReviewHelpfulVote.objects.filter(review=self.pk, helpful=True).count() # Gets the total number of votes which marked this review as 'unhelpful'. - def getUnhelpfulVoteCount(self): - return ReviewHelpfulVote.objects.filter(pk=self.pk, helpful=False).count() + @property + def unhelpful_vote_count(self): + return ReviewHelpfulVote.objects.filter(review=self.pk, helpful=False).count() # A vote for a review as either positive or negative. class ReviewHelpfulVote(models.Model): @@ -75,8 +77,6 @@ class ReviewHelpfulVote(models.Model): review = models.ForeignKey('postings.Review', on_delete=models.CASCADE) # Whether or not the referenced review was helpful. helpful = models.BooleanField() - # The user who made this vote. - user = models.ForeignKey('postings.User', on_delete=models.CASCADE) # A RateableEntity for universities. class University(RateableEntity): diff --git a/backend/postings/static/postings/js/voting.js b/backend/postings/static/postings/js/voting.js index c65915b..26a6a6c 100644 --- a/backend/postings/static/postings/js/voting.js +++ b/backend/postings/static/postings/js/voting.js @@ -33,6 +33,27 @@ // }); // }); +// Sends either an up- or down-vote for a particular review. +function sendVote (event, is_helpful) { + var csrf_token = $('#csrf-token input').val(); + var review_id = $(event.target).closest('.js_votes').data('review_id'); + var data = { + 'csrfmiddlewaretoken': csrf_token, + 'helpful': is_helpful + }; + $.post( + '/api/postings/reviews/' + review_id + '/helpful_vote/', + data, + ) + .done(function (response) { + console.log(response); + }) + .fail(function (response) { + console.log(response); + }); +} + +// Registers all events to the document. function registerEvents () { $(document.body) .off('click.js_vote_up') @@ -41,6 +62,7 @@ function registerEvents () { function (event) { event.preventDefault(); console.log("updoot"); + sendVote(event, true); }); $(document.body) @@ -50,6 +72,7 @@ function registerEvents () { function (event) { event.preventDefault(); console.log("downdoot"); + sendVote(event, false); }); } diff --git a/backend/postings/templates/postings/frontend/review.html b/backend/postings/templates/postings/frontend/review.html index 41ab8bc..0cbb7d6 100644 --- a/backend/postings/templates/postings/frontend/review.html +++ b/backend/postings/templates/postings/frontend/review.html @@ -19,14 +19,14 @@
{{ review.title }}
{{ review.content }}
-
+
Was this review helpful? - Yes - No + Yes + No
- {{ review.getHelpfulVoteCount }} / - {{ review.getUnhelpfulVoteCount }} + {{ review.helpful_vote_count }} / + {{ review.unhelpful_vote_count }}
\ No newline at end of file