from django.contrib.contenttypes.fields import GenericRelation
from django.db import models

from adhocracy4.comments import models as comment_models
from adhocracy4.models.base import UserGeneratedContentModel
from adhocracy4.modules import models as module_models

from . import validators


class Poll(module_models.Item):
    comments = GenericRelation(comment_models.Comment,
                               related_query_name='poll',
                               object_id_field='object_pk')


class Question(models.Model):
    label = models.CharField(max_length=255)
    weight = models.SmallIntegerField()

    poll = models.ForeignKey(
        'Poll',
        on_delete=models.CASCADE,
        related_name='questions'
    )

    def user_choices_list(self, user):
        if not user.is_authenticated():
            return []

        return self.choices\
            .filter(votes__creator=user)\
            .values_list('id', flat=True)

    def __str__(self):
        return self.label

    class Meta:
        ordering = ['weight']


class ChoiceQuerySet(models.QuerySet):

    def annotate_vote_count(self):
        return self.annotate(
            vote_count=models.Count(
                'votes'
            )
        )


class Choice(models.Model):
    label = models.CharField(max_length=255)

    question = models.ForeignKey(
        'Question',
        on_delete=models.CASCADE,
        related_name='choices',
    )

    objects = ChoiceQuerySet.as_manager()

    def __str__(self):
        return '%s @%s' % (self.label, self.question)


class Vote(UserGeneratedContentModel):
    choice = models.ForeignKey(
        'Choice',
        on_delete=models.CASCADE,
        related_name='votes'
    )

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

    # Make Vote instances behave like items for rule checking
    @property
    def module(self):
        self.choice.question.poll.module

    @property
    def project(self):
        return self.module.project

    def __str__(self):
        return '%s: %s' % (self.creator, self.choice)

apps/polls/models.py
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models

from adhocracy4.comments import models as comment_models
from adhocracy4.models.base import UserGeneratedContentModel
from adhocracy4.modules import models as module_models

from . import validators


class Poll(module_models.Item):
    comments = GenericRelation(comment_models.Comment,
                               related_query_name='poll',
                               object_id_field='object_pk')


class Question(models.Model):
    label = models.CharField(max_length=255)
    weight = models.SmallIntegerField()

    poll = models.ForeignKey(
        'Poll',
        on_delete=models.CASCADE,
        related_name='questions'
    )

    def user_choices_list(self, user):
        if not user.is_authenticated():
            return []

        return self.choices\
            .filter(votes__creator=user)\
            .values_list('id', flat=True)

    def __str__(self):
        return self.label

    class Meta:
        ordering = ['weight']


class ChoiceQuerySet(models.QuerySet):

    def annotate_vote_count(self):
        return self.annotate(
            vote_count=models.Count(
                'votes'
            )
        )


class Choice(models.Model):
    label = models.CharField(max_length=255)

    question = models.ForeignKey(
        'Question',
        on_delete=models.CASCADE,
        related_name='choices',
    )

    objects = ChoiceQuerySet.as_manager()

    class Meta:
        ordering = ['id']

    def __str__(self):
        return '%s @%s' % (self.label, self.question)


class Vote(UserGeneratedContentModel):
    choice = models.ForeignKey(
        'Choice',
        on_delete=models.CASCADE,
        related_name='votes'
    )

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

    # Make Vote instances behave like items for rule checking
    @property
    def module(self):
        self.choice.question.poll.module

    @property
    def project(self):
        return self.module.project

    def __str__(self):
        return '%s: %s' % (self.creator, self.choice)

apps/polls/models.py
diff --git a/apps/polls/models.py b/apps/polls/models.py
index 49dc2bd7a2..a2dcda5069 100644
--- a/apps/polls/models.py
+++ b/apps/polls/models.py
@@ -60,6 +60,9 @@ class Choice(models.Model):
 
     objects = ChoiceQuerySet.as_manager()
 
+    class Meta:
+        ordering = ['id']
+
     def __str__(self):
         return '%s @%s' % (self.label, self.question)
 

Order of poll answer choices mixed up after saving
The order of poll answer choices is mixed up after saving. Restoring original order is not possible:
![bildschirmfoto 2017-05-12 um 17 11 59](https://cloud.githubusercontent.com/assets/11075214/26004427/226d3d8c-3736-11e7-8759-ccf91a1e1da8.png)

