我想从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')
视图
class OneZeroViewSet(viewsets.ModelViewSet):
serializer_class = OneZeroSerializer(realpart=1)
#serializer_class = OneZeroSerializer
queryset = OneZero.objects.all()
基本上我想根据查询字符串将一些值传递给Serializer类,然后将这些值分配给字段。
这些字段未包含在模型中,实际上是动态创建的字段。
此问题stackoverflow中的情况相同,但我无法理解答案。
在这种情况下,任何人都可以帮助我,或者建议我提供更好的选择。
答案 0 :(得分:72)
使用“ModelSerializer”构造函数的“context”arg非常容易。
例如:
在视图中:
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”获取额外的参数。
答案 1 :(得分:19)
要完成redcyb的答案 - 请考虑在您的视图中使用get_serializer_context
中的GenericAPIView
方法,如下所示:
def get_serializer_context(self):
return {'user': self.request.user.email}
答案 2 :(得分:15)
您需要在查看覆盖get_serializer_context
方法,如下所示:
def get_serializer_context(self):
return {"customer_id": self.kwargs['customer_id']}
以及serializer
中的任何地方都可以获得它:
customer_id = self.context["customer_id"]
答案 3 :(得分:7)
我编写的旧代码,可能有助于过滤嵌套的序列化程序:
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):
.....
希望这可以帮助人们寻找这个。
答案 4 :(得分:0)
这些答案太复杂了;如果您有任何类型的身份验证,则将此属性添加到您的序列化程序并调用它以访问发送请求的用户。
类 BaseSerializer(serializers.ModelSerializer):
@property
def sent_from_user(self):
return self.context['request'].user