robtus88
robtus88

Reputation: 490

Allow 1 view generation per user in Django

Having this question I came up with the code below.

The behavior should be as follows:

  1. each Suggestion can receive several Vote
  2. Only 1 Vote per user is allowed

It 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

Answers (1)

user8060120
user8060120

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

Related Questions