【问题标题】:Django Combine Many Unrelated Models on Related Foreign KeyDjango在相关外键上组合了许多不相关的模型
【发布时间】:2021-11-16 08:11:58
【问题描述】:

我有 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 查询创建输出,该输出还包括所有 Q 的 e_id=1,因此它看起来像这样:

[
 {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 对象的一些附加,只要我在它的末尾有一个符合我可以发送的需要的序列化结果作为 API 响应的 JSON 对象。

【问题讨论】:

    标签: python django django-models django-rest-framework django-queryset


    【解决方案1】:

    这可以通过像这样编写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 实例中查找Qs 的列表(在这种情况下,所有QTE 相关) .

    但您还必须编写另一个Q 序列化程序以不显示Q 内的E(根据需要仅idname_q):

    class QInTSerializer(ModelSerializer):
        class Meta:
            model = Q
            fields = ('id', 'name_q')
    

    如果您计划通过选择相关的E 对象并从E 预取相关的Q 对象来序列化多个T 对象,您还可以节省数据库命中:

    t = T.objects.select_related('e').prefetch_related('e__q_set')
    

    【讨论】:

    • 谢谢@BrianD 你能解释一下e.q_set 代表什么吗?因为尝试上述我得到一个错误'E' object has no attribute 'q_set'
    • T访问Q对象。很像t = T.objects.first(); t.e.q_set.all()q_set 是从 e 访问 q 的相关名称。
    猜你喜欢
    • 2012-05-07
    • 2021-10-04
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 2019-01-29
    • 2021-05-07
    • 2022-11-13
    • 2019-10-01
    相关资源
    最近更新 更多