我正在将一个相当复杂的自制表单转换为Django中的ModelForm
。由于这种形式在生产中使用了一年多,我试图尽可能多地删除陷阱并为用户提供额外的功能。
我有三个模型:Transaction
,Commission
和Unit_type
。 Transaction
是我使用的核心模型,有一个Unit_type
。 Commission
源自Unit_type
的{{1}}。
base_type
当我显示表单时,我只能使用以下内容显示与BASE_CHOICES = (
('R', 'rent'),
('S', 'sale'),
)
class Unit_type(models.Model):
unit_name = models.CharField(max_length=250)
base_type = models.CharField(max_length=1, choices=BASE_CHOICES)
class Commission(models.Model):
commission_name = models.CharField(max_length=250)
base_type = models.CharField(max_length=1, choices=BASE_CHOICES)
class Transaction(models.Models):
unit_type = models.ForeignKey(Unit_type)
commission = models.ForeignKey(Commission, blank=True, null=True)
具有相同base_type的Commission
:
Unit_type
我总是在我的视图中将我的表单创建为class TransactionForm(forms.ModelForm):
class Meta:
model = Transaction
def __init__(self, unit_type, *args, **kwargs):
super(TransactionForm, self).__init__(*args, **kwargs)
self.fields['commission'].queryset = Commission_type.objects.filter(base_type=unit_type.base_type)
。
现在,在MySQL中一个简单的查询了解到,根据所选的TransactionForm(instance=transaction, unit_type=unit_type)
,一些Commission
或多或少被使用:
Unit
结果:
SELECT `unit_type_id`, `commission_id`, COUNT(*)
FROM `app_transaction`
GROUP BY `unit_type_id`, `commission_id`
现在我想基于上面的计数在+----------------+-----------------+------------+
| unit_type_id | commission_id | COUNT(*) |
+----------------+-----------------+------------+
| 1 | 1 | 367 |
| 1 | 3 | 2 |
| 1 | 4 | 26 |
| 2 | 1 | 810 |
| 2 | 3 | 54 |
| 2 | 4 | 865 |
| 3 | 6 | 2065 |
| 3 | 7 | 16 |
| 3 | 8 | 79 |
+----------------+-----------------+------------+
中订购我的查询集。我已尝试在self.fields['commission']
中使用values()
:
__init__()
但现在我仍然坚持如何在查询集中保持此顺序。是否有一种基于此def __init__(self, unit, *args, **kwargs):
super(TransactionForm, self).__init__(*args, **kwargs)
transactions = Transaction.objects.filter(unit_type=unit)
transactions = transactions.values('commission').annotate(Count('commission)).order_by('-commission')
执行新查询集的简单方法?或者我看到这完全错了吗?
答案 0 :(得分:1)
你只需要使用一个kwarg for Count并在order_by
中使用相同的kwarg
transactions = transactions.annotate(commission_count=Count('commission)).order_by('-commission_count')
https://docs.djangoproject.com/en/1.5/topics/db/aggregation/#cheat-sheet
答案 1 :(得分:1)
你不能只执行一次查询操作来设置你的查询集,因为filter()和annotate()不是终结子句吗?
self.fields['commission'].queryset = Commission_type.objects.filter(base_type=unit_type.base_type).annotate(Count('commission)).order_by('-commission')
这将根据您的过滤器()然后注释()回答一个查询集。