Подтвердить что ты не робот

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

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

В основном я хотел бы знать, как перейти от:

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

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

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

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

4b9b3361

Ответ 1

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}

Ответ 2

Возврат родительского контекста в переопределенной функции 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

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

Ответ 3

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

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

def perform_create(self, serializer):

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

    serializer.save()

Ответ 4

просто используйте get_serializer() в ваших представлениях

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)