Python 将额外的参数传递给 Django Rest Framework 中的序列化器类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22988878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 02:05:27  来源:igfitidea点击:

Pass extra arguments to Serializer Class in Django Rest Framework

pythondjangorestdjango-rest-framework

提问by Shoaib Ijaz

I want to pass some arguments to DRF Serializer class from Viewset, so for I have tried this:

我想将一些参数从 Viewset 传递给 DRF Serializer 类,因此我尝试过:

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')

Views

观看次数

class OneZeroViewSet(viewsets.ModelViewSet):

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

   queryset = OneZero.objects.all()

Basically I want to pass some value based on querystring from views to Serializer class and then these will be allocate to fields.

基本上我想将一些基于查询字符串的值从视图传递给 Serializer 类,然后这些值将分配给字段。

These fields are not include in Model in fact dynamically created fields.

这些字段不包含在模型中,实际上是动态创建的字段。

Same case in this question stackoverflow, but I cannot understand the answer.

这个问题stackoverflow 中的情况相同,但我无法理解答案。

Can anyone help me in this case or suggest me better options.

任何人都可以在这种情况下帮助我或建议我更好的选择。

回答by yeaske

A old code I wrote, that might be helpful- done to filter nested serializer:

我写的旧代码,可能对过滤嵌套序列化器有所帮助:

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')

How to override get_serializer_class:

如何覆盖 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):
       .....

Hope this helps people looking for this.

希望这可以帮助人们寻找这个。

回答by redcyb

It's very easy with "context" arg for "ModelSerializer" constructor.

“ModelSerializer”构造函数的“上下文”参数非常容易。

For example:

例如:

in view:

鉴于:

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

in serializers:

在序列化程序中:

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
...

so you can use "self.context" for getting extra params.

所以你可以使用“self.context”来获取额外的参数。

Reference

参考

回答by andilabs

To fulfill the answer of redcyb - consider using in your view the get_serializer_contextmethod from GenericAPIView, like this:

为了实现 redcyb 的答案 - 考虑在您的视图中使用get_serializer_context来自的方法GenericAPIView,如下所示:

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

回答by M.Void

You need in the Viewoverride get_serializer_contextmethod like this:

你需要像这样的视图覆盖get_serializer_context方法:

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

and anywhere in the serializeryou can get it:

serializer你可以在任何地方得到它:

customer_id = self.context["customer_id"]