3

感谢这篇文章,我可以轻松地在 Django 视图中按查询进行计数和分组:

Django 等效于 count 和 group by

我在我的应用程序中所做的是显示一个国家/地区数据库中可用的硬币类型和面值列表,因此来自英国的硬币可能具有“1 法特”或“6 便士”的面值。是face_value6,currency_type是“便士”,存储在相关表中。

在我看来,我有以下代码可以让我完成 90% 的工作:

def coins_by_country(request, country_name):
    country = Country.objects.get(name=country_name)
    coin_values = Collectible.objects.filter(country=country.id, type=1).extra(select={'count': 'count(1)'},
                               order_by=['-count']).values('count', 'face_value', 'currency_type')
    coin_values.query.group_by = ['currency_type_id', 'face_value']
    return render_to_response('icollectit/coins_by_country.html', {'coin_values': coin_values, 'country': country } )

currency_type_id作为存储在外键字段中的数字(即 4)。我想要做的是检索它作为查询的一部分引用的实际对象(货币模型,因此我可以在模板中获取 Currency.name 字段)。

最好的方法是什么?

4

3 回答 3

2

你不能用values(). 但是没有必要使用它——你可以只获取实际的Collectible对象,每个对象都有一个currency_type属性,该属性将是相关的链接对象。

正如 justinhamade 所建议的那样,使用select_related()将有助于减少数据库查询的数量。

把它放在一起,你得到:

coin_values = Collectible.objects.filter(country=country.id, 
                    type=1).extra(
                    select={'count': 'count(1)'}, 
                    order_by=['-count']
                ).select_related()
于 2009-07-16T19:13:18.103 回答
1

select_related()让我非常接近,但它希望我将我选择的每个字段都添加到group_by子句中。

所以我尝试values()select_related(). 不去。然后我在查询的不同位置尝试了每种排列的各种排列。关闭,但不完全。

由于我已经知道如何编写 SQL 查询,因此我最终“退出”并只使用原始 SQL。

def coins_by_country(request, country_name):
    country = get_object_or_404(Country, name=country_name)
    cursor = connection.cursor()
    cursor.execute('SELECT count(*), face_value, collection_currency.name FROM collection_collectible, collection_currency WHERE collection_collectible.currency_type_id = collection_currency.id AND country_id=%s AND type=1 group by face_value, collection_currency.name', [country.id] )
    coin_values = cursor.fetchall()
    return render_to_response('icollectit/coins_by_country.html', {'coin_values': coin_values, 'country': country } )

如果有一种方法可以用 Django 查询集语言来表达那个确切的查询,我很想知道。我想带有计数和按两列分组的 SQL 连接并不是非常罕见,所以如果没有干净的方法,我会感到惊讶。

于 2009-07-17T14:33:54.627 回答
0

您是否尝试过 select_related() http://docs.djangoproject.com/en/dev/ref/models/querysets/#id4

我经常使用它,它似乎工作得很好,然后你可以去 coin_values.currency.name。

另外,我认为您不需要在过滤器中执行 country=country.id,只需 country=country 但我不确定除了减少输入之外还有什么不同。

于 2009-07-16T16:29:09.167 回答