Объедините несколько наборов запросов из разных базовых моделей Django - PullRequest
12 голосов
/ 18 июля 2011

У меня сейчас две разные модели.

class Journal(models.Model):
    date = models.DateField()
    from_account = models.ForeignKey(Account,related_name='transferred_from')
    to_account = models.ForeignKey(Account,related_name='transferred_to')
    amount = models.DecimalField(max_digits=8, decimal_places=2)
    memo = models.CharField(max_length=100,null=True,blank=True)

class Ledger(models.Model):
    date = models.DateField()
    bank_account = models.ForeignKey(EquityAccount,related_name='paid_from')
    account = models.ForeignKey(Account)
    amount = models.DecimalField(max_digits=8, decimal_places=2)
    name = models.ForeignKey(Party)
    memo = models.CharField(max_length=100,null=True,blank=True)

Я создаю отчет в виде и получаю следующую ошибку: Объединение классов «ValuesQuerySet» должно включать одинаковые значения в каждом случае.

То, что я пытаюсь сделать, это только вытащить общие поля, чтобы я мог объединить их оба, например

def report(request):

    ledger = GeneralLedger.objects.values('account').annotate(total=Sum('amount'))
    journal = Journal.objects.values('from_account').annotate(total=Sum('amount'))
    report = ledger & journal
...

Если я попытаюсь сделать их точно такими же, например,

def report(request):

    ledger = GeneralLedger.objects.values('memo').annotate(total=Sum('amount'))
    journal = Journal.objects.values('memo').annotate(total=Sum('amount'))
    report = ledger & journal
...

Я получаю эту ошибку: Невозможно объединить запросы для двух разных базовых моделей.

Кто-нибудь знает, как это можно сделать?

Ответы [ 2 ]

22 голосов
/ 18 июля 2011
from itertools import chain
report = chain(ledger, journal)

Itertools за выигрыш!

Если вы хотите создать Союз, вы должны преобразовать эти querysets в объекты python set.

Если возможно правильно отфильтровать сам набор запросов, вам действительно следует это сделать!

1 голос
/ 14 сентября 2018

Используйте itertools.chain :

from itertools import chain
report = list(chain(ledger, journal))

Примечание: вам нужно превратить полученный объект в список, чтобы Django мог его обработать.

...