3

我正在将一个相当复杂的自制形式转换为ModelFormDjango 中的一个。由于这种形式在生产中使用了一年多,我正在尝试尽可能多地消除陷阱并为用户提供额外的功能。

我有三个模型TransactionCommissionUnit_typeTransaction是我使用中的中心模型,并且有一个Unit_type. Commission是从Unit_type's派生的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)

当我显示我的表单时,我只能显示与使用Commission具有相同 base_type 的 s 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)

我总是按照TransactionForm(instance=transaction, unit_type=unit_type)我的观点创建我的表单。

现在,MySQL 中的一个简单查询告诉我,Commission根据所选内容或多或少地使用了一些 s 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()in __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')

但现在我被困在如何在我的查询集中保持这个顺序。有没有一种简单的方法可以基于此执行新的查询集ValuesQuerySet?还是我认为这完全错误?

4

2 回答 2

1

你不能只执行一个查询操作来设置你的查询集,因为 filter() 和 annotate() 不是终端子句吗?

self.fields['commission'].queryset = Commission_type.objects.filter(base_type=unit_type.base_type).annotate(Count('commission)).order_by('-commission')

这将根据您的 filter() 然后 annotate() 回答查询集。

于 2013-08-24T16:28:39.833 回答
1

您只需要为 Count 使用一个 kwarg 并在order_by

transactions = transactions.annotate(commission_count=Count('commission)).order_by('-commission_count')

https://docs.djangoproject.com/en/1.5/topics/db/aggregation/#cheat-sheet

于 2013-08-21T09:15:09.067 回答