Reputation: 490
Having this question I came up with the code below.
The behavior should be as follows:
Suggestion
can receive several Vote
Vote
per user is allowedIt works fine but I was wondering what's the best way to do this?
vote_form.html
<form action="{% url 'add_vote' suggestion.id %}" method="post">
{% csrf_token %}
<input type="submit" value="I want to vote">
</form>
urls.py
urlpatterns = [
url(r'^suggestion/(?P<pk>\d+)/$', views.SuggestionDetail.as_view(), name="suggestion_detail"),
url(r'^suggestion/(?P<pk>\d+)/vote/$', views.add_vote, name='add_vote'),
]
models.py
class Vote(models.Model):
suggestion = models.ForeignKey(Suggestion)
voter = models.ForeignKey('auth.User')
vote_count = models.BooleanField()
views.py
def add_vote(request, pk):
suggestion = get_object_or_404(Suggestion, pk=pk)
vote = Vote(
suggestion = suggestion,
voter = request.user,
vote_count = True)
has_user_voted = Vote.objects.filter(voter=request.user, suggestion=suggestion).count()
if has_user_voted < 1:
vote.save()
else:
messages.error(request, 'It seems you have already voted, only one vote is allowed')
return HttpResponseRedirect(reverse('suggestion_detail', args=(suggestion.id,)))
Upvotes: 1
Views: 89
Reputation:
first solution is add unique-together in your model
class Vote(models.Model):
suggestion = models.ForeignKey(Suggestion)
voter = models.ForeignKey('auth.User')
vote_count = models.BooleanField()
class Meta:
unique_together = ("suggestion", "voter")
if vote_count
always is True
you can also use get-or-create
def add_vote(request, pk):
suggestion = get_object_or_404(Suggestion, pk=pk)
vote, created = Vote.objects.get_or_create(
voter=request.user,
suggestion=suggestion,
vote_count=True)
if not created:
messages.error(request, 'It seems you have already voted, only one vote is allowed')
return HttpResponseRedirect(reverse('suggestion_detail', args=(suggestion.id,)))
Upvotes: 2