Added views to create, update and delete MotionPoll objects.

This commit is contained in:
Norman Jäckel 2015-07-22 15:23:57 +02:00
parent 6b747c8cef
commit a1f1cfed1f
4 changed files with 79 additions and 5 deletions

View File

@ -216,7 +216,7 @@ class AssignmentViewSet(ModelViewSet):
raise ValidationError({'detail': _('Can not create poll because there are no candidates.')})
with transaction.atomic():
assignment.create_poll()
return Response({'detail': _(' Poll created successfully.')})
return Response({'detail': _('Poll created successfully.')})
class AssignmentPollViewSet(UpdateModelMixin, DestroyModelMixin, GenericViewSet):

View File

@ -18,7 +18,7 @@ class MotionsAppConfig(AppConfig):
from openslides.core.signals import config_signal
from openslides.utils.rest_api import router
from .signals import create_builtin_workflows, setup_motion_config
from .views import CategoryViewSet, MotionViewSet, WorkflowViewSet
from .views import CategoryViewSet, MotionViewSet, MotionPollViewSet, WorkflowViewSet
# Connect signals.
config_signal.connect(setup_motion_config, dispatch_uid='setup_motion_config')
@ -27,4 +27,5 @@ class MotionsAppConfig(AppConfig):
# Register viewsets.
router.register('motions/category', CategoryViewSet)
router.register('motions/motion', MotionViewSet)
router.register('motions/motionpoll', MotionPollViewSet)
router.register('motions/workflow', WorkflowViewSet)

View File

@ -4,6 +4,7 @@ from django.utils.translation import ugettext as _
from openslides.core.config import config
from openslides.utils.rest_api import (
CharField,
DictField,
IntegerField,
ModelSerializer,
PrimaryKeyRelatedField,
@ -107,15 +108,50 @@ class MotionPollSerializer(ModelSerializer):
Serializer for motion.models.MotionPoll objects.
"""
motionoption_set = MotionOptionSerializer(many=True, read_only=True)
votes = DictField(
child=IntegerField(min_value=-2),
write_only=True)
class Meta:
model = MotionPoll
fields = (
'id',
'poll_number',
'motionoption_set',
'votesvalid',
'votesinvalid',
'votescast',)
'votescast',
'votes',)
read_only_fields = ('poll_number',)
@transaction.atomic
def update(self, instance, validated_data):
"""
Customized update method for polls. To update votes use the write
only field 'votes'.
Example data:
"votes": {"Yes": 10, "No": 4, "Abstain": -2}
"""
# Update votes.
votes = validated_data.get('votes')
if votes:
if len(votes) != len(instance.get_vote_values()):
raise ValidationError({
'detail': _('You have to submit data for %d vote values.') % len(instance.get_vote_values())})
for vote_value, vote_weight in votes.items():
if vote_value not in instance.get_vote_values():
raise ValidationError({
'detail': _('Vote value %s is invalid.') % vote_value})
instance.set_vote_objects_with_values(instance.get_options().get(), votes)
# Update remaining writeable fields.
instance.votesvalid = validated_data.get('votesvalid', instance.votesvalid)
instance.votesinvalid = validated_data.get('votesinvalid', instance.votesinvalid)
instance.votescast = validated_data.get('votescast', instance.votescast)
instance.save()
return instance
class MotionVersionSerializer(ModelSerializer):

View File

@ -1,3 +1,4 @@
from django.db import transaction
from django.http import Http404
from django.shortcuts import get_object_or_404
from django.utils.text import slugify
@ -8,17 +9,22 @@ from rest_framework import status
from openslides.core.config import config
from openslides.utils.rest_api import (
DestroyModelMixin,
GenericViewSet,
ModelViewSet,
Response,
UpdateModelMixin,
ValidationError,
detail_route,
)
from openslides.utils.views import PDFView, SingleObjectMixin
from .exceptions import WorkflowError
from .models import Category, Motion, MotionPoll, MotionVersion, Workflow
from .pdf import motion_poll_to_pdf, motion_to_pdf, motions_to_pdf
from .serializers import (
CategorySerializer,
MotionPollSerializer,
MotionSerializer,
WorkflowSerializer,
)
@ -31,7 +37,8 @@ class MotionViewSet(ModelViewSet):
API endpoint for motions.
There are the following views: metadata, list, retrieve, create,
partial_update, update, destroy, manage_version, support and set_state.
partial_update, update, destroy, manage_version, support, set_state and
create_poll.
"""
queryset = Motion.objects.all()
serializer_class = MotionSerializer
@ -49,7 +56,7 @@ class MotionViewSet(ModelViewSet):
self.request.user.has_perm('motions.can_create') and
(not config['motions_stop_submitting'] or
self.request.user.has_perm('motions.can_manage')))
elif self.action in ('destroy', 'manage_version', 'set_state'):
elif self.action in ('destroy', 'manage_version', 'set_state', 'create_poll'):
result = (self.request.user.has_perm('motions.can_see') and
self.request.user.has_perm('motions.can_manage'))
elif self.action == 'support':
@ -231,6 +238,36 @@ class MotionViewSet(ModelViewSet):
person=request.user)
return Response({'detail': message})
@detail_route(methods=['post'])
def create_poll(self, request, pk=None):
"""
View to create a poll. It is a POST request without any data.
"""
motion = self.get_object()
try:
with transaction.atomic():
motion.create_poll()
except WorkflowError as e:
raise ValidationError({'detail': e})
return Response({'detail': _('Poll created successfully.')})
class MotionPollViewSet(UpdateModelMixin, DestroyModelMixin, GenericViewSet):
"""
API endpoint for motion polls.
There are the following views: update and destroy.
"""
queryset = MotionPoll.objects.all()
serializer_class = MotionPollSerializer
def check_view_permissions(self):
"""
Returns True if the user has required permissions.
"""
return (self.request.user.has_perm('motions.can_see') and
self.request.user.has_perm('motions.can_manage'))
class CategoryViewSet(ModelViewSet):
"""