OpenSlides/server/openslides/poll/serializers.py

130 lines
4.0 KiB
Python
Raw Normal View History

from django.conf import settings
2019-10-29 09:44:19 +01:00
from ..utils.auth import get_group_model
from ..utils.rest_api import (
CharField,
DecimalField,
IdPrimaryKeyRelatedField,
ModelSerializer,
SerializerMethodField,
ValidationError,
2019-10-29 09:44:19 +01:00
)
from .models import BasePoll
2019-10-29 09:44:19 +01:00
BASE_VOTE_FIELDS = ("id", "weight", "value", "user", "option", "pollstate")
class BaseVoteSerializer(ModelSerializer):
pollstate = SerializerMethodField()
def get_pollstate(self, vote):
return vote.option.poll.state
BASE_OPTION_FIELDS = ("id", "yes", "no", "abstain", "poll_id", "pollstate")
2019-10-29 09:44:19 +01:00
class BaseOptionSerializer(ModelSerializer):
yes = DecimalField(max_digits=15, decimal_places=6, min_value=-2, read_only=True)
no = DecimalField(max_digits=15, decimal_places=6, min_value=-2, read_only=True)
abstain = DecimalField(
max_digits=15, decimal_places=6, min_value=-2, read_only=True
)
pollstate = SerializerMethodField()
def get_pollstate(self, option):
return option.poll.state
2019-10-29 09:44:19 +01:00
2019-10-18 14:18:49 +02:00
BASE_POLL_FIELDS = (
"state",
"type",
"title",
"groups",
"votesvalid",
"votesinvalid",
"votescast",
"options",
"id",
2019-10-29 09:44:19 +01:00
"onehundred_percent_base",
"majority_method",
"voted",
2019-10-18 14:18:49 +02:00
)
2019-10-29 09:44:19 +01:00
class BasePollSerializer(ModelSerializer):
title = CharField(allow_blank=False, required=True)
groups = IdPrimaryKeyRelatedField(
many=True, required=False, queryset=get_group_model().objects.all()
)
options = IdPrimaryKeyRelatedField(many=True, read_only=True)
voted = IdPrimaryKeyRelatedField(many=True, read_only=True)
2019-10-29 09:44:19 +01:00
votesvalid = DecimalField(
max_digits=15, decimal_places=6, min_value=-2, read_only=True
)
votesinvalid = DecimalField(
max_digits=15, decimal_places=6, min_value=-2, read_only=True
)
votescast = DecimalField(
max_digits=15, decimal_places=6, min_value=-2, read_only=True
)
def create(self, validated_data):
"""
Match the 100 percent base to the pollmethod. Change the base, if it does not
fit to the pollmethod
"""
new_100_percent_base = self.norm_100_percent_base_to_pollmethod(
validated_data["onehundred_percent_base"], validated_data["pollmethod"]
)
if new_100_percent_base is not None:
validated_data["onehundred_percent_base"] = new_100_percent_base
return super().create(validated_data)
def update(self, instance, validated_data):
"""
Adjusts the 100%-base to the pollmethod. This might be needed,
if at least one of them was changed. Wrong combinations should be
2019-10-29 09:44:19 +01:00
also handled by the client, but here we make it sure aswell!
E.g. the pollmethod is YN, but the 100%-base is YNA, this might not be
2019-10-29 09:44:19 +01:00
possible (see implementing serializers to see forbidden combinations)
"""
old_100_percent_base = instance.onehundred_percent_base
instance = super().update(instance, validated_data)
new_100_percent_base = self.norm_100_percent_base_to_pollmethod(
instance.onehundred_percent_base, instance.pollmethod, old_100_percent_base
)
if new_100_percent_base is not None:
instance.onehundred_percent_base = new_100_percent_base
instance.save()
return instance
def validate(self, data):
"""
Check that the given polltype is allowed.
"""
# has to be called in function instead of globally to enable tests to change the setting
ENABLE_ELECTRONIC_VOTING = getattr(settings, "ENABLE_ELECTRONIC_VOTING", False)
if (
"type" in data
and data["type"] != BasePoll.TYPE_ANALOG
and not ENABLE_ELECTRONIC_VOTING
):
raise ValidationError(
{
"detail": "Electronic voting is disabled. Only analog polls are allowed"
}
)
return data
2019-10-29 09:44:19 +01:00
def norm_100_percent_base_to_pollmethod(
self, onehundred_percent_base, pollmethod, old_100_percent_base=None
):
raise NotImplementedError()