Python 如何使用 Django Rest Framework 包含相关模型字段?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14573102/
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
How do I include related model fields using Django Rest Framework?
提问by Chaz
Let's say that we have the following model:
假设我们有以下模型:
class Classroom(models.Model):
room_number = [....]
class Teacher(models.Model):
name = [...]
tenure = [...]
classroom = models.ForeignKey(Classroom)
Let's say that instead of getting a result like this per the ManyRelatedPrimaryKeyField function:
假设不是根据 ManyRelatedPrimaryKeyField 函数获得这样的结果:
{
"room_number": "42",
"teachers": [
27,
24,
7
]
},
have it return something that includes the full related model representation like:
让它返回包含完整相关模型表示的内容,例如:
{
"room_number": "42",
"teachers": [
{
'id':'27,
'name':'John',
'tenure':True
},
{
'id':'24,
'name':'Sally',
'tenure':False
},
]
},
Is this possible? If so, how? And is this a bad idea?
这可能吗?如果是这样,如何?这是一个坏主意吗?
采纳答案by Tom Christie
The simplest way is to use the depth argument
最简单的方法是使用depth 参数
class ClassroomSerializer(serializers.ModelSerializer):
class Meta:
model = Classroom
depth = 1
However, that will only include relationships for forward relationships, which in this case isn't quite what you need, since the teachers field is a reverse relationship.
但是,这仅包括正向关系的关系,在这种情况下,这不是您所需要的,因为教师字段是反向关系。
If you've got more complex requirements (eg. include reverse relationships, nest some fields, but not others, or nest only a specific subset of fields) you can nest serializers, eg...
如果您有更复杂的要求(例如,包括反向关系,嵌套某些字段,但不嵌套其他字段,或仅嵌套特定的字段子集),则可以嵌套序列化程序,例如...
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = ('id', 'name', 'tenure')
class ClassroomSerializer(serializers.ModelSerializer):
teachers = TeacherSerializer(source='teacher_set')
class Meta:
model = Classroom
Note that we use the source argument on the serializer field to specify the attribute to use as the source of the field. We could drop the sourceargument by instead making sure the teachersattribute exists by using the related_nameoption on your Teachermodel, ie. classroom = models.ForeignKey(Classroom, related_name='teachers')
请注意,我们在序列化器字段上使用 source 参数来指定用作字段源的属性。我们可以source通过在模型上teachers使用related_name选项来确保属性存在来删除参数Teacher,即。classroom = models.ForeignKey(Classroom, related_name='teachers')
One thing to keep in mind is that nested serializers do not currently support write operations. For writable representations, you should use regular flat representations, such as pk or hyperlinking.
要记住的一件事是嵌套序列化程序目前不支持写操作。对于可写表示,您应该使用常规平面表示,例如 pk 或超链接。
回答by Eliyahu Tauber
Thank you @TomChristie!!! You helped me a lot! I would like to update that a little (because of a mistake I ran into)
谢谢@TomChristie!!!你帮了我很多!我想稍微更新一下(因为我遇到了一个错误)
class TeacherSerializer(serializers.ModelSerializer):
class Meta:
model = Teacher
fields = ('id', 'name', 'tenure')
class ClassroomSerializer(serializers.ModelSerializer):
teachers = TeacherSerializer(source='teacher_set', many=True)
class Meta:
model = Classroom
field = ("teachers",)
回答by Paul Tuckett
This can also be accomplished by using a pretty handy dandy django packaged called drf-flex-fields. We use it and it's pretty awesome. You just install it pip install drf-flex-fields, pass it through your serializer, add expandable_fieldsand bingo (example below). It also allows you to specify deep nested relationships by using dot notation.
这也可以通过使用一个非常方便的dandydjango 打包来完成,称为drf-flex-fields。我们使用它,它非常棒。你只需安装它pip install drf-flex-fields,通过你的序列化程序,添加expandable_fields和宾果游戏(下面的例子)。它还允许您使用点表示法指定深层嵌套关系。
from rest_flex_fields import FlexFieldsModelSerializer
class ClassroomSerializer(FlexFieldsModelSerializer):
class Meta:
model = Model
fields = ("teacher_set",)
expandable_fields = {"teacher_set": (TeacherSerializer, {"source": "teacher_set"})}
Then you add ?expand=teacher_setto your URL and it returns an expanded response.
Hope this helps someone, someday. Cheers!
然后你添加?expand=teacher_set到你的 URL,它返回一个扩展的响应。希望这有助于某人,有一天。干杯!

