我正在尝试使用 Django 进行简单的复式记账。目前,每笔交易都是一个对象,借方和贷方账户是外键。现在,我正在尝试取出所有交易对象,以便每笔交易都有借方和贷方对象,并且我可以轻松地在模板中排序和表示每个帐户的交易和总计。所以每个交易对象在最终结果中都需要有借方对象和贷方对象。我认为在 MySQL 中你可以通过以下方式实现这一点:
SELECT date, description, amount, debit_account AS account, debit AS 1 FROM Transaction
UNION
SELECT date, description, amount, credit_account AS account, debit AS 0 FROM Transaction
在 Django 中使用 Python 对象执行此操作的正确方法是什么? Union 似乎覆盖了我当前的 for 循环中的更改,最终我没有区分借方和贷方。
models.py
class Transaction(models.Model):
date = models.DateField()
description = models.CharField(max_length=150)
debit_account = models.ForeignKey('ledger.Account', related_name='debit_account', blank=True, null=True, on_delete=models.CASCADE)
credit_account = models.ForeignKey('ledger.Account', related_name='credit_account', blank=True, null=True, on_delete=models.CASCADE)
amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
debit_in_ledger = models.BooleanField(default=False)
views.py
def ledger(request):
transaction_list_debit = Transaction.objects.all()
transaction_list_credit = Transaction.objects.all()
for a in transaction_list_debit:
a.debit_in_ledger = True
transaction_list = transaction_list_debit.union(transaction_list_credit, all=True).order_by('debit_account', 'public_date')
return render(request, 'pages/ledger.html', {'transaction_list' : transaction_list})
最佳答案
您可以按如下方式执行此操作:
from django.db.models import BooleanField, F, Value
q1 = Transaction.objects.annotate(
account = F('debit_account')
debit = Value(True, output_field=BooleanField())
)
q2 = Transaction.objects.annotate(
account = F('credit_account')
debit = Value(False, output_field=BooleanField())
)
qs = q1 | q2
哪里qs
因此是我们的“最终”查询集。这个QuerySet
将包含Transaction
对象,以及每个 Transaction
查询集中的对象将具有两个额外属性:account
和debit
。请注意其他属性,如 debit_account
等仍然存在。此外,每个真实 Transaction
因此,在数据库中将出现两次:一次来自 q1
,一次来自 q2
.
此外.account
将包含相关 Account
的主键,所以不是对 Account
的引用。然后您可以获取 Account
与 Account.objects.get(pk=some_transaction.account)
.
关于python - Django 中的查询集联合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51921756/