Skip to content

Commit

Permalink
polls/validators//models: add validation that only vote can be create…
Browse files Browse the repository at this point in the history
…d per choice per user
  • Loading branch information
rine authored and fuzzylogic2000 committed Aug 31, 2021
1 parent aaafd1f commit a4d786b
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
11 changes: 11 additions & 0 deletions apps/polls/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from adhocracy4.comments import models as comment_models
from adhocracy4.models.base import UserGeneratedContentModel
from adhocracy4.modules import models as module_models
from apps.polls.validators import single_vote_per_user


class QuestionQuerySet(models.QuerySet):
Expand Down Expand Up @@ -99,6 +100,16 @@ class Vote(UserGeneratedContentModel):
related_name='votes'
)

def save(self, *args, **kwargs):
self.validate_unique()
return super().save(*args, **kwargs)

def validate_unique(self, exclude=None):
super(Vote, self).validate_unique(exclude)
single_vote_per_user(self.creator,
self.choice,
self.pk)

# Make Vote instances behave like items for rule checking
@property
def module(self):
Expand Down
10 changes: 3 additions & 7 deletions apps/polls/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,17 @@ def single_item_per_module(module, model, pk=None):
def single_vote_per_user(user, choice, pk=None):
from .models import Vote # avoid circular import

if choice.question.multiple_choice:
# Allow multiple votes per user for multiple choice questions.
return

qs = Vote.objects\
.filter(choice__question=choice.question)\
.filter(creator=user)
.filter(choice=choice,
creator=user)

if pk:
qs = qs.exclude(pk=pk)

if qs.exists():
raise ValidationError({
NON_FIELD_ERRORS: [
_('Only one vote per question is allowed per user.'),
_('Only one vote per choice is allowed per user.'),
]
})

Expand Down

0 comments on commit a4d786b

Please sign in to comment.