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

Передайте дополнительные аргументы классу Serializer в Django Rest Framework

Я хочу передать некоторые аргументы классу Serializer DRF из Viewset, так что я пробовал это:

class OneZeroSerializer(rest_serializer.ModelSerializer):

    def __init__(self, *args, **kwargs):
        print args # show values that passed

    location = rest_serializer.SerializerMethodField('get_alternate_name')

    def get_alternate_name(self, obj):
        return ''


    class Meta:
        model = OneZero

        fields = ('id', 'location')

Просмотры

class OneZeroViewSet(viewsets.ModelViewSet):

   serializer_class = OneZeroSerializer(realpart=1)
   #serializer_class = OneZeroSerializer

   queryset = OneZero.objects.all()

В принципе, я хочу передать некоторое значение на основе querystring из представлений в класс Serializer, а затем они будут выделяться полям.

Эти поля не включают в модель фактически динамически созданные поля.

Тот же случай в этом вопросе qaru.site/info/144253/..., но я не могу понять ответ.

Может ли кто-нибудь помочь мне в этом случае или предложить мне лучшие варианты.

4b9b3361

Ответ 1

Это очень легко с "context" arg для конструктора ModelSerializer.

Например:

в поле зрения:

my_objects = MyModelSerializer(
    input_collection, 
    many=True, 
    context={'user_id': request.user.id}
).data

в сериализаторах:

class MyModelSerializer(serializers.ModelSerializer):
...

    is_my_object = serializers.SerializerMethodField('_is_my_find')
...

    def _is_my_find(self, obj):
        user_id = self.context.get("user_id")
        if user_id:
            return user_id in obj.my_objects.values_list("user_id", flat=True)
        return False
...

чтобы вы могли использовать "self.context" для получения дополнительных параметров.

Ссылка

Ответ 2

Чтобы выполнить ответ redcyb - рассмотрим использование в вашем представлении метода get_serializer_context из GenericAPIView, например:

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

Ответ 3

Вам нужно использовать метод Вид переопределить get_serializer_context следующим образом:

def get_serializer_context(self):
    return {"customer_id": self.kwargs['customer_id']}

и в любом месте serializer вы можете получить его:

customer_id = self.context["customer_id"]

Ответ 4

Старый код, который я написал, может быть полезен для фильтрации вложенного сериализатора:

class MySerializer(serializers.ModelSerializer):

    field3  = serializers.SerializerMethodField('get_filtered_data')

    def get_filtered_data(self, obj):
        param_value = self.context['request'].QUERY_PARAMS.get('Param_name', None)
        if param_value is not None:
            try:
                data = Other_model.objects.get(pk_field=obj, filter_field=param_value)
            except:
                return None
            serializer = OtherSerializer(data)
            return serializer.data
        else:
            print "Error stuff"

    class Meta:
        model = Model_name
        fields = ('filed1', 'field2', 'field3')

Как переопределить get_serializer_class:

class ViewName(generics.ListAPIView):

    def get_serializer_class(self):
        param_value = self.context['request'].QUERY_PARAMS.get('Param_name', None)
        if param_value is not None:
            return Serializer1
        else:
            return Serializer2

    def get_queryset(self):
       .....

Надеюсь, это поможет людям, которые ищут это.