Django在与同一模型相关的几个字段上进行注释

时间:2016-01-20 12:09:08

标签: python django

我有两种模式:

class Account(models.Model):
    ...

class Transaction(models.Model):
    ....
    account = models.ForeignKey(Account)
    source_account = models.ForeignKey(Account, null=True)

我需要显示每个用户帐户的交易数量。 Django的annotate似乎是完成这项任务的合适工具。我做了:

queryset = models.Account.objects.filter(user=self.request.user)
queryset.annotate(transactions_count=Count('transaction'))

这为设置为谓词帐户的account字段的交易提供了正确的数字,但省略了将source_account设置为谓词帐户的交易。

使用Django shell我可以执行以下操作:

accounts_count = user_transactions.filter(Q(account=account)|Q(source_account=account)).count()

这给出了正确的答案。有什么我做错了吗?有人能指出我正确的方向。任何帮助都非常感谢。

2 个答案:

答案 0 :(得分:2)

我会将related_name设置为您的ForeignKey字段。然后使用它们会更容易一些。例如,在您的模型中设置:

class Transaction(models.Model):
    ...
    account = models.ForeignKey(Account, related_name='transactions')
    source_account = models.ForeignKey(Account, null=True, related_name='source_transactions')
然后可以做类似的事情:

 queryset = models.Account.objects.filter(user=self.request.user).annotate(transactions_count=(Count('transactions')+Count('source_transactions'))

它没有命名也可以工作,它更易读,更容易。重点是在Count中将两个annotate添加为一个字段。

解决这些类型问题的最佳方法是在原始SQL中设想它们,然后尝试在Django ORM中模仿它。 (在原始sql中,您只需添加两列,如SELECT (a.col + a.col2) AS count

答案 1 :(得分:0)

问题是您的交易必须是ForgeinKeys帐户。我建议尝试这样的事情

class Transaction(models.Model):
    ....
    account = models.ForeignKey(Account, related_name="transaction_account")
    source_account = models.ForeignKey(Account, null=True, related_name="transaction_source_account")

然后在你的查询中:

queryset.annotate(transactions_count=((Count('transaction_account') +  Count('transaction_source_account'))