Игнорирование определенных полей при обновлении в зависимости от условия
Описание:
Цель - обновить все Spotlight поля на PUT/PATCH (update/partial update), если его status является YELLOW.
Если status является RED || GREEN, он должен обновлять только свои status и игнорировать любые другие поля. Обходной путь, представленный здесь, является несколько вонючим, и он дает вводящие в заблуждение ответы при использовании PUT.
Есть ли в Django способ добиться этого лучше, чем представленное обходное решение?
Исходный вариант:
if instance.state == instance.STATE_YELLOW:
custom_data = request.data
else:
custom_data = {'state': request.data['state']}
Полный код:
from stoplight.filters import StoplightFilter
from stoplight.models import Stoplight
from stoplight.permissions import (
IsSuperuserOrReadOnly
)
from stoplight.serializers import StoplightSerializer
from rest_framework import status
from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
class StoplightViewSet(GenericViewSet, CreateModelMixin, ListModelMixin, RetrieveModelMixin):
"""
API endpoint for Stoplights
"""
queryset = Stoplight.objects.all()
serializer_class = StoplightSerializer
filter_class = StoplightFilter
search_fields = ('name',)
permission_classes = (IsSuperuserOrReadOnly,)
def update(self, request, *args, **kwargs):
"""
Updates Stoplight state
"""
partial = kwargs.pop('partial', False)
instance = self.get_object()
if instance.state == instance.STATE_YELLOW:
custom_data = request.data
else:
custom_data = {'state': request.data['state']}
serializer = self.get_serializer(instance, data=custom_data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
return Response(serializer.data, status=status.HTTP_200_OK)
def perform_update(self, serializer):
serializer.save()
def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.update(request, *args, **kwargs)