Передать контекст запроса сериализатору из Viewset в Django Rest Framework

у меня есть случай, когда значения для поля сериализатора зависят от идентификатора текущего зарегистрированного пользователя. Я видел, как Добавить пользователя в контекст при инициализации сериализатора, но я не уверен, как это сделать при использовании набора представлений, поскольку вы предоставляете только класс сериализатора, а не фактический экземпляр сериализатора.

в основном, я хотел бы знать, как идти с:

class myModelViewSet(ModelViewSet):
   queryset = myModel.objects.all()
   permission_classes = [DjangoModelPermissions]
   serializer_class = myModelSerializer

в:

class myModelSerializer(serializers.ModelSerializer):
    uploaded_by = serializers.SerializerMethodField()
    special_field = serializers.SerializerMethodField()

    class Meta:
        model = myModel

    def get_special_field(self, obj):
        if self.context['request'].user.has_perm('something.add_something'):
           return something

Извините, если это не было ясно, от доктора: Добавление Дополнительного Контекста Что говорит делать

serializer = AccountSerializer(account, context={'request': request})
serializer.data

но я не уверен, как это сделать автоматически из набора представлений, так как я могу изменить только класс сериализатора, а не сам экземпляр сериализатора.

4 ответов


GenericViewSet имеет get_serializer_context метод, который вы можете переопределить:

class myModelViewSet(ModelViewSet):
    queryset = myModel.objects.all()
    permission_classes = [DjangoModelPermissions]
    serializer_class = myModelSerializer

    def get_serializer_context(self):
        return {'request': self.request}

возврат родительского контекста в переопределенной функции get_serializer_context облегчит доступ к запросу и его данным.

 class myModelViewSet(ModelViewSet):
       queryset = myModel.objects.all()
       permission_classes = [DjangoModelPermissions]
       serializer_class = myModelSerializer

       def get_serializer_context(self):
       """
       pass request attribute to serializer
       """
           context = super(myModelViewSet, self).get_serializer_context()
           return context

Это очень стабильно, так как каждый раз, когда мы запрашиваем viewset, он также возвращает контекст.


значения поля сериализатора зависят от идентификатора текущего зарегистрированного пользователя

вот как я обрабатываю такие случаи в моем ModelViewSet:

def perform_create(self, serializer):

    user = self.request.user
    if user.username == 'myuser':
        serializer.data['myfield'] = 'something'

    serializer.save()

просто использовать get_serializer() в viewsets

def get_serializer(self, *args, **kwargs):
    """
    Return the serializer instance that should be used for validating and
    deserializing input, and for serializing output.
    """
    serializer_class = self.get_serializer_class()
    kwargs['context'] = self.get_serializer_context()
    return serializer_class(*args, **kwargs)