Django: выбор столбцов в разных приложениях с одним и тем же внешним ключом
Это последующий вопрос из этого.
У меня app1/models.py
:
class A(models.Model):
id = models.IntegerField(primary_key=True)
text = models.CharField(max_length=20)
class B(models.Model):
fid = models.ForeignKey(A, models.CASCADE)
text = models.CharField(max_length=20)
class C(models.Model):
fid = models.ForeignKey(A, models.CASCADE)
text = models.CharField(max_length=20)
и app2/models.py
:
from app1.models import A
class D(models.Model):
fid = models.ForeignKey(A, models.CASCADE)
text = models.CharField(max_length=20)
Я хочу получить A.text
B.text
C.text
D.text
где A.id == B.fid == C.fid == D.fid == 1
. Из приведенного вопроса я смог получить первые 3 столбца, используя:
B.objects.filter(fid=1).values('text', 'fid__text', 'fid__c__text') # B.text, A.text, C.text
Однако я не могу получить D.text
с помощью этого запроса. Я знаю, что могу сделать фильтр на D
и вычислить его вручную, но я надеюсь на более Djangoic способ.
(В случае многократного совпадения, просуммируйте строки, таким образом, если в B
есть 2 строки, которые соответствуют данному fid
и 3, 4 для C
, D
, всего будет возвращено 24 строки)
Попробовать запрос из A
модели
A.objects.filter(id=1).values('text', 'b__text', 'c__text', 'd__text')
Я не знаю, почему это не работает. Может быть, это ошибка базы данных? В этом случае Django может быть не при чем. Работает ли это, если заменить fid__c__text
на fid__d__text
?
Я бы инстинктивно запросил экземпляр модели A
, который является "родителем" остальных. Получив экземпляр a
, он предлагает b_set.all()
, c_set.all()
и d_set.all()
. Для эффективности работы БД вы можете предварительно получить все связанные объекты с помощью
a = A.objects.prefetch_related('b', 'c', 'd').get( pk=b.fid_id )
(Обратите внимание, что при предварительной выборке фильтрация осуществляется путем итерации по a.b_set.all()
, а не путем применения .filter(criteria)
, который снова попадет в БД независимо от предварительной выборки).