Django 在相关外键上组合许多不相关的模型
Django Combine Many Unrelated Models on Related Foreign Key
我有 3 个型号 T、E、Q,因此:
class E(Model):
name_e = CharField()
class T(Model):
name_t = CharField()
e = ForeignKey(E)
class Q(Model):
name_q = CharField()
e = ForeignKey(E)
我也有每个序列化程序:
class ESerializer(ModelSerializer):
class Meta:
model = E
fields = '__all__'
class TSerializer(ModelSerializer):
e = ESerializer()
class Meta:
model = T
fields = '__all__'
class QSerializer(ModelSerializer):
e = ESerializer()
class Meta:
model = Q
fields = '__all__'
对于一个 E 行,可以有多个 T 和 Q 行。
我可以这样查询
t = T.objects.filter(e__id=1).all()
serialized_t = TSerializer(t, many=True).data
serialized_t
的输出类似于:
[
{id:7, name_t:'test_1', e:{id:1, name_e:'ename_1'}},
{id:9, name_t:'test_2', e:{id:1, name_e:'ename_1'}}
]
我的问题是如何将它组合起来,以便我可以在上面的查询中包含 Q 以创建 T 查询的输出,其中还包含 e_id=1 处的所有 Q,因此它看起来像这样:
[
{id:7, name_t:'test_1', e:{id:1, name_e:'ename_1'}, q:[{id:4, name_q:'qname_1'}, {id:5, name_q:'qname_2'}]},
{id:9, name_t:'test_2', e:{id:1, name_e:'ename_1'}, q:[{id:4, name_q:'qname_1'}, {id:5, name_q:'qname_2'}]}
]
我不介意这是否可以在查询中完成,或者它是否涉及对 SerializedT 对象的一些附加,只要我在它的末尾有一个符合我需要的序列化结果可以作为 JSON 对象作为 API 响应发送。
这可以通过像这样编写 T
序列化程序来完成:
class TSerializer(ModelSerializer):
e = ESerializer()
q = QInTSerializer(source='e.q_set', many=True)
class Meta:
model = T
fields = '__all__'
这将构建一个 q
字段,表示 Q
个对象的列表。指定 source='e.q_set'
是为了告诉字段从正在序列化的 T
实例中查找 Q
列表的位置(在这种情况下,所有 Q
都与 T
的E
).
但是您还必须编写另一个 Q
序列化程序以不在 Q
中显示 E
(仅根据需要显示 id
和 name_q
):
class QInTSerializer(ModelSerializer):
class Meta:
model = Q
fields = ('id', 'name_q')
如果您计划通过选择相关的 E
对象并从 [=21= 中预取相关的 Q
对象来序列化多个 T
对象,您还可以节省数据库点击量]:
t = T.objects.select_related('e').prefetch_related('e__q_set')
我有 3 个型号 T、E、Q,因此:
class E(Model):
name_e = CharField()
class T(Model):
name_t = CharField()
e = ForeignKey(E)
class Q(Model):
name_q = CharField()
e = ForeignKey(E)
我也有每个序列化程序:
class ESerializer(ModelSerializer):
class Meta:
model = E
fields = '__all__'
class TSerializer(ModelSerializer):
e = ESerializer()
class Meta:
model = T
fields = '__all__'
class QSerializer(ModelSerializer):
e = ESerializer()
class Meta:
model = Q
fields = '__all__'
对于一个 E 行,可以有多个 T 和 Q 行。 我可以这样查询
t = T.objects.filter(e__id=1).all()
serialized_t = TSerializer(t, many=True).data
serialized_t
的输出类似于:
[
{id:7, name_t:'test_1', e:{id:1, name_e:'ename_1'}},
{id:9, name_t:'test_2', e:{id:1, name_e:'ename_1'}}
]
我的问题是如何将它组合起来,以便我可以在上面的查询中包含 Q 以创建 T 查询的输出,其中还包含 e_id=1 处的所有 Q,因此它看起来像这样:
[
{id:7, name_t:'test_1', e:{id:1, name_e:'ename_1'}, q:[{id:4, name_q:'qname_1'}, {id:5, name_q:'qname_2'}]},
{id:9, name_t:'test_2', e:{id:1, name_e:'ename_1'}, q:[{id:4, name_q:'qname_1'}, {id:5, name_q:'qname_2'}]}
]
我不介意这是否可以在查询中完成,或者它是否涉及对 SerializedT 对象的一些附加,只要我在它的末尾有一个符合我需要的序列化结果可以作为 JSON 对象作为 API 响应发送。
这可以通过像这样编写 T
序列化程序来完成:
class TSerializer(ModelSerializer):
e = ESerializer()
q = QInTSerializer(source='e.q_set', many=True)
class Meta:
model = T
fields = '__all__'
这将构建一个 q
字段,表示 Q
个对象的列表。指定 source='e.q_set'
是为了告诉字段从正在序列化的 T
实例中查找 Q
列表的位置(在这种情况下,所有 Q
都与 T
的E
).
但是您还必须编写另一个 Q
序列化程序以不在 Q
中显示 E
(仅根据需要显示 id
和 name_q
):
class QInTSerializer(ModelSerializer):
class Meta:
model = Q
fields = ('id', 'name_q')
如果您计划通过选择相关的 E
对象并从 [=21= 中预取相关的 Q
对象来序列化多个 T
对象,您还可以节省数据库点击量]:
t = T.objects.select_related('e').prefetch_related('e__q_set')