我有两个模型。 Bar 通过外键与 Foo 相关联。在我的 Bar 序列化器中,我有 FooSerializer,因此它可以从其模型中序列化:
class BarSerializer(serializers.ModelSerializer):
foo = FooSerializer(source='*')
...
class Meta:
model = Bar
然后我的 Foo Serializer 看起来像:
class FooSerializer(serializers.ModelSerializer):
name = serializers.StringRelatedField()
link = serializers.SerializerMethodField()
class Meta:
model = Foo
fields = ('name', 'link')
def to_internal_value(self, data):
# Save depending on name
foo = Foo.objects.get(name=data)
return {'foo': foo}
def get_link(self, object):
print('req', object.id)
if object.id and request:
return request.build_absolute_uri(
'/app/foo/{}'.format(object.id))
return None
我希望能够使用 Foo 的 name
字段在 Bar 中发帖,例如:
{
"bar_name": "Nikko",
"foo": "The Foo",
}
但我想要的回应是:
{
"bar_name": "Nikko",
"foo": {
"name": "The Foo",
"link": "https://localhost:8000/apps/foo/1",
}
}
答案 0 :(得分:1)
这是可能的。您需要将一个字段设为只写,而将另一个设为只读:
class BarSerializer(serializers.ModelSerializer):
foo = FooSerializer(source='*', read_only=True)
foo_write = serializers.SlugRelatedField(slug_field='name', queryset=Foo.objects.all(), write_only=True)
...
class Meta:
model = Bar
我使用 SlugRelatedField,它可以让您使用 name 属性来搜索 Foo 实例。它假定 Name 字段是唯一的,否则您将无法检索到正确的实例。
您可能需要在 source="Foo"
上添加 SlugRelatedField
,如果它不能重新识别它所指的字段。
答案 1 :(得分:0)
如果您想要自定义响应,则必须覆盖 to_represendation(self, instance)
。 drf-doc
如果您想添加额外的 context
并从 request
获取信息,您可以这样添加
serializer = FooSerializer(..., context={'request': request})
获取请求数据,在您的 self.context
中使用 to_representation()