Django объединяет множество несвязанных моделей по связанному внешнему ключу

У меня есть 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 = E
        fields = '__all__'

class QSerializer(ModelSerializer):
    e = ESerializer()
    class Meta:
        model = E
        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, пока у меня есть сериализованный результат в конце, который соответствует моим потребностям, который я могу отправить как объект 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' служит для указания полю, где искать этот список Q из сериализуемого экземпляра T (в данном случае, все Q, относящиеся к T к E).

Но вы также должны написать еще один сериализатор Q, чтобы не отображать E внутри Q (только id и name_q, как требуется):

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

Вы также можете сэкономить на обращениях к БД, если планируете сериализовать несколько T объектов, выбрав связанный E объект и предварительно получив связанные Q объекты из E:

t = T.objects.select_related('e').prefetch_related('e__q_set')
Вернуться на верх