OpenSlides/openslides/motions/serializers.py

229 lines
6.5 KiB
Python
Raw Normal View History

from django.db import transaction
from django.utils.translation import ugettext as _
from openslides.config.api import config
from openslides.utils.rest_api import (
CharField,
IntegerField,
ModelSerializer,
PrimaryKeyRelatedField,
ValidationError,)
from .models import (
Category,
Motion,
MotionLog,
MotionOption,
MotionPoll,
MotionVersion,
MotionVote,
State,
Workflow,)
def validate_workflow_field(value):
"""
Validator to ensure that the workflow with the given id exists.
"""
if not Workflow.objects.filter(pk=value).exists():
raise ValidationError(_('Workflow %(pk)d does not exist.') % {'pk': value})
class CategorySerializer(ModelSerializer):
"""
Serializer for motion.models.Category objects.
"""
class Meta:
model = Category
fields = ('id', 'name', 'prefix',)
class StateSerializer(ModelSerializer):
"""
Serializer for motion.models.State objects.
"""
class Meta:
model = State
fields = (
'id',
'name',
'action_word',
'icon',
'required_permission_to_see',
'allow_support',
'allow_create_poll',
'allow_submitter_edit',
'versioning',
'leave_old_version_active',
'dont_set_identifier',
'next_states',)
class WorkflowSerializer(ModelSerializer):
"""
Serializer for motion.models.Workflow objects.
"""
state_set = StateSerializer(many=True, read_only=True)
first_state = PrimaryKeyRelatedField(read_only=True)
class Meta:
model = Workflow
fields = ('id', 'name', 'state_set', 'first_state',)
class MotionLogSerializer(ModelSerializer):
"""
Serializer for motion.models.MotionLog objects.
"""
class Meta:
model = MotionLog
fields = ('message_list', 'person', 'time',)
class MotionVoteSerializer(ModelSerializer):
"""
Serializer for motion.models.MotionVote objects.
"""
class Meta:
model = MotionVote
fields = ('value', 'weight',)
class MotionOptionSerializer(ModelSerializer):
"""
Serializer for motion.models.MotionOption objects.
"""
motionvote_set = MotionVoteSerializer(many=True, read_only=True)
class Meta:
model = MotionOption
fields = ('motionvote_set',)
class MotionPollSerializer(ModelSerializer):
"""
Serializer for motion.models.MotionPoll objects.
"""
motionoption_set = MotionOptionSerializer(many=True, read_only=True)
class Meta:
model = MotionPoll
fields = (
'poll_number',
'motionoption_set',
'votesvalid',
'votesinvalid',
'votescast',)
class MotionVersionSerializer(ModelSerializer):
"""
Serializer for motion.models.MotionVersion objects.
"""
class Meta:
model = MotionVersion
fields = (
'id',
'version_number',
'creation_time',
'title',
'text',
'reason',)
class MotionSerializer(ModelSerializer):
"""
Serializer for motion.models.Motion objects.
"""
active_version = PrimaryKeyRelatedField(read_only=True)
log_messages = MotionLogSerializer(many=True, read_only=True)
polls = MotionPollSerializer(many=True, read_only=True)
reason = CharField(allow_blank=True, required=False, write_only=True)
state = StateSerializer(read_only=True)
text = CharField(write_only=True)
title = CharField(max_length=255, write_only=True)
versions = MotionVersionSerializer(many=True, read_only=True)
workflow = IntegerField(min_value=1, required=False, validators=[validate_workflow_field])
class Meta:
model = Motion
fields = (
'id',
'identifier',
'title',
'text',
'reason',
'versions',
'active_version',
'parent',
'category',
'submitters',
'supporters',
'state',
'workflow',
'tags',
'attachments',
'polls',
'log_messages',)
read_only_fields = ('parent',) # Some other fields are also read_only. See definitions above.
@transaction.atomic
def create(self, validated_data):
"""
Customized method to create a new motion from some data.
"""
motion = Motion()
motion.title = validated_data['title']
motion.text = validated_data['text']
motion.reason = validated_data.get('reason', '')
motion.identifier = validated_data.get('identifier')
motion.category = validated_data.get('category')
motion.reset_state(validated_data.get('workflow', int(config['motion_workflow'])))
motion.save()
if validated_data['submitters']:
motion.submitters.add(*validated_data['submitters'])
else:
motion.submitters.add(validated_data['request_user'])
motion.supporters.add(*validated_data['supporters'])
motion.attachments.add(*validated_data['attachments'])
motion.tags.add(*validated_data['tags'])
return motion
@transaction.atomic
def update(self, motion, validated_data):
"""
Customized method to update a motion.
"""
# Identifier and category.
for key in ('identifier', 'category'):
if key in validated_data.keys():
setattr(motion, key, validated_data[key])
# Workflow.
workflow = validated_data.get('workflow')
if workflow is not None and workflow != motion.workflow:
motion.reset_state(workflow)
# Decide if a new version is saved to the database.
if (motion.state.versioning and
not validated_data.get('disable_versioning', False)): # TODO
version = motion.get_new_version()
else:
version = motion.get_last_version()
# Title, text, reason.
for key in ('title', 'text', 'reason'):
if key in validated_data.keys():
setattr(version, key, validated_data[key])
motion.save(use_version=version)
# Submitters, supporters, attachments and tags
for key in ('submitters', 'supporters', 'attachments', 'tags'):
if key in validated_data.keys():
attr = getattr(motion, key)
attr.clear()
attr.add(*validated_data[key])
return motion