EventSpecificSerializer and EventSpecificViewSet defined

This commit is contained in:
Qwann 2017-07-22 00:56:30 +02:00
parent 92e8e374fd
commit 48f9fd516d
3 changed files with 61 additions and 49 deletions

View file

@ -1,7 +1,34 @@
from django.shortcuts import get_object_or_404
from rest_framework import serializers
from event.models import Event, ActivityTag, Place, ActivityTemplate
# Classes utilitaires
class EventSpecificSerializer(serializers.HyperlinkedModelSerializer):
"""
Provide `update` and `create` methods for nested view with an Event
For example for Models which exetends EventSpecificMixin
the event id has to be provided in the `save` method
Works fine with view.EventSpecificViewSet
"""
def update(self, instance, validated_data):
"""
Note : does NOT change the event value of the instance
"""
validated_data.pop('event_pk')
[setattr(instance, key, value)
for key, value in validated_data.items()]
instance.save()
return instance
def create(self, validated_data):
ModelClass = self.Meta.model
event_pk = validated_data.pop('event_pk', None)
event = get_object_or_404(Event, id=event_pk)
instance = ModelClass.objects.create(event=event, **validated_data)
return instance
class EventSerializer(serializers.HyperlinkedModelSerializer):
created_by = serializers.ReadOnlyField(source='created_by.username')
@ -12,35 +39,13 @@ class EventSerializer(serializers.HyperlinkedModelSerializer):
# TODO rajouter des permissions
class PlaceSerializer(serializers.HyperlinkedModelSerializer):
event = EventSerializer(allow_null=True)
class PlaceSerializer(EventSpecificSerializer):
event = EventSerializer(allow_null=True, read_only=True)
class Meta:
model = Place
fields = ('url', 'id', 'name', 'description', 'event')
def update(self, instance, validated_data):
try:
data = validated_data.pop('event')
event = Event.objects.get_object_or_404(**data)
except KeyError:
event = None
[setattr(instance, key, value)
for key, value in validated_data.items()]
setattr(instance, 'event', event)
instance.save()
return instance
def create(self, validated_data):
ModelClass = self.Meta.model
try:
data = validated_data.pop('event')
event = Event.objects.get_object_or_404(**data)
except KeyError:
event = None
instance = ModelClass.objects.create(event=event, **validated_data)
return instance
# TODO rajouter des permissions
class ActivityTagSerializer(serializers.HyperlinkedModelSerializer):

View file

@ -1,15 +1,42 @@
from django.contrib.auth import get_user_model
from django.db.models import Q
from rest_framework.viewsets import ModelViewSet, ViewSet
from rest_framework.viewsets import ModelViewSet
from api.event.serializers import EventSerializer, PlaceSerializer,\
ActivityTagSerializer, ActivityTemplateSerializer
from api.event.mixins import EventNestedMixin
from event.models import Event, Place, ActivityTag, ActivityTemplate
User = get_user_model()
# classes utilitaires
class EventSpecificViewSet(ModelViewSet):
"""
ViewSet that returns :
* rootlevel objects if no Event is specified
* OR objects related to the specidied event
AND root level objects
if an event is specified it passes the event_pk
to the save method. Works fine with serializers.EventSpecificSerializer
Useful for models that exetends EventSpecificMixin
"""
def get_queryset(self):
"""
Warning : You may want to override this method
and not call with super
"""
event_pk = self.kwargs.get('event_pk')
queryset = super().get_queryset()
if event_pk:
return queryset.filter(Q(event=event_pk) | Q(event=None))
return queryset.filter(event=None)
def perform_create(self, serializer):
event_pk = self.kwargs.get('event_pk')
serializer.save(event_pk=event_pk)
class EventViewSet(ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
@ -23,31 +50,11 @@ class EventViewSet(ModelViewSet):
serializer.save(created_by=self.request.user)
class PlaceViewSet(ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
"""
class PlaceViewSet(EventSpecificViewSet):
queryset = Place.objects.all()
serializer_class = PlaceSerializer
class PlaceEventViewSet(ModelViewSet):
queryset = Place.objects.all()
serializer_class = PlaceSerializer
def list(self, request, event_pk=None):
queryset = self.queryset.filter(event=event_pk)
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
class ActivityTagViewSet(ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,

View file

@ -1,7 +1,7 @@
from django.conf.urls import url, include
from rest_framework_nested.routers import SimpleRouter, NestedSimpleRouter
from api.event.views import EventViewSet, PlaceViewSet, ActivityTagViewSet,\
ActivityTemplateViewSet, PlaceEventViewSet
ActivityTemplateViewSet
# Create a router and register our viewsets with it.
router = SimpleRouter()
@ -12,7 +12,7 @@ router.register(r'activitytemplate', ActivityTemplateViewSet)
# Register nested router and register someviewsets vith it
event_router = NestedSimpleRouter(router, r'event', lookup='event')
event_router.register(r'place', PlaceEventViewSet, base_name='event-names')
event_router.register(r'place', PlaceViewSet, base_name='event-names')
# The API URLs are now determined automatically by the router.