我对Django比较新。我在过滤数据时遇到问题。我有两个模型,如下所示:
Account(models.Model):
name = models.CharField(max_length=60)
hotel = models.ForeignKey(Hotel)
account_type = models.CharField(choices=ACCOUNT_TYPE, max_length=30)
Transaction(models.Model):
account = models.ForeignKey(Account, related_name='transaction')
transaction_type = models.CharField(choices=TRANSACTION_TYPE, max_length=15)
description = models.CharField(max_length=100, blank=True, null=True)
date_created = models.DateTimeField(default=timezone.now)
ACCOUT_TYPE 是:
ACCOUNT_TYPE = (
(0, 'Asset'),
(1, 'Liabilities'),
(2, 'Equity'),
(3, 'Income'),
(4, 'Expense')
)
我想过滤指定日期范围内帐户类型为Income
和Expense
的所有交易。如何在Django中组合这些过滤器?
我试过这样的话:
income_account = Account.objects.filter(account_type=3)
expense_account = Account.objects.filter(account_type=4)
transactions = Transaction.objects.filter(Q(
account=income_account,
date_created__gte=request.data['start_date'],
date_created__lte=request.data['end_date']
) & Q(
account=expense_account,
date_created__gte=request.data['start_date'],
date_created__lte=request.data['end_date'])).order_by('date_created')
但它没有用。它引发了以下错误:
ProgrammingError: more than one row returned by a subquery used as an expression
答案 0 :(得分:2)
income_account
和expense_account
不是单个对象,而是一个对象列表。因此,不是account=income_account
而是account=expense_account
尝试使用in
:account__in=income_account
和account__in=expense_account
。
你也可以像这样简化查询集:
accounts = Account.objects.filter(Q(account_type=3) | Q(account_type=4))
transactions = Transaction.objects.filter(
account__in=accounts,
date_created__gte=request.data['start_date'],
date_created__lte=request.data['end_date']
).order_by('date_created')
答案 1 :(得分:1)
您可以只使用一个查询集,而不是拥有多个查询集,因为Q
允许OR
过滤器。你可以这样做:
Transaction.objects.filter(
(Q(account__account_type=3) | Q(account__account_type=4)) &
Q(date_created__range=[start_date, end_date])
)
__range
可用于获取指定的start_date
和end_date
之间的日期。
答案 2 :(得分:1)
您始终可以使用MSG_CONFIRM
按多个值查找记录。因此,如果您希望in
Transaction
ACCOUNT_TYPE
Income, Expense
,您可以像这样使用它。
Transaction.objects.filter(Q(account__in=[3,4]) & Q(date_created__gte=request.data['start_date']) & Q(date_created__lte=request.data['end_date'])).order_by('date_created')
答案 3 :(得分:0)
这对你有用: -
result = Account.objects.filter((account_type__in['Income','Expense'])
OR
result = Account.objects.filter((account_type__in['0','4'])
我已将0和4作为字符串,因为您已将account_type视为CharField。