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 rest_framework import serializers
from event.models import Event, ActivityTag, Place, ActivityTemplate 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): class EventSerializer(serializers.HyperlinkedModelSerializer):
created_by = serializers.ReadOnlyField(source='created_by.username') created_by = serializers.ReadOnlyField(source='created_by.username')
@ -12,35 +39,13 @@ class EventSerializer(serializers.HyperlinkedModelSerializer):
# TODO rajouter des permissions # TODO rajouter des permissions
class PlaceSerializer(serializers.HyperlinkedModelSerializer): class PlaceSerializer(EventSpecificSerializer):
event = EventSerializer(allow_null=True) event = EventSerializer(allow_null=True, read_only=True)
class Meta: class Meta:
model = Place model = Place
fields = ('url', 'id', 'name', 'description', 'event') 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 # TODO rajouter des permissions
class ActivityTagSerializer(serializers.HyperlinkedModelSerializer): class ActivityTagSerializer(serializers.HyperlinkedModelSerializer):

View file

@ -1,15 +1,42 @@
from django.contrib.auth import get_user_model 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,\ from api.event.serializers import EventSerializer, PlaceSerializer,\
ActivityTagSerializer, ActivityTemplateSerializer ActivityTagSerializer, ActivityTemplateSerializer
from api.event.mixins import EventNestedMixin
from event.models import Event, Place, ActivityTag, ActivityTemplate from event.models import Event, Place, ActivityTag, ActivityTemplate
User = get_user_model() 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): class EventViewSet(ModelViewSet):
""" """
This viewset automatically provides `list`, `create`, `retrieve`, This viewset automatically provides `list`, `create`, `retrieve`,
@ -23,31 +50,11 @@ class EventViewSet(ModelViewSet):
serializer.save(created_by=self.request.user) serializer.save(created_by=self.request.user)
class PlaceViewSet(ModelViewSet): class PlaceViewSet(EventSpecificViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
"""
queryset = Place.objects.all() queryset = Place.objects.all()
serializer_class = PlaceSerializer 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): class ActivityTagViewSet(ModelViewSet):
""" """
This viewset automatically provides `list`, `create`, `retrieve`, This viewset automatically provides `list`, `create`, `retrieve`,

View file

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