2009-07-16 25 views
2

感谢这个帖子,我能够很容易地做计数和组通过查询在Django视图:如何获取相关对象在Django中的extra()。values()调用中?

Django equivalent for count and group by

我在做什么我的应用程序是显示硬币的类型和面值列表在我的数据库中可以找到一个国家,所以来自英国的硬币的面值可能是“1 farthing”或“6便士”。 face_value是6,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字段)。

这样做的最佳方法是什么?

回答

1

select_related()让我相当接近,但要我补充一点,我选择到group_by条款各个领域。

所以我试着在select_related()之后追加values()。不行。然后我尝试了查询中不同位置的各种排列。关闭,但不完全。

因为我已经知道如何编写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 queryset语言中精确查询,我会很想知道。我想象一下SQL连接的计数和两列分组并不是非常罕见的,所以如果没有一个干净的方法,我会感到惊讶。

0

你试过select_related()http://docs.djangoproject.com/en/dev/ref/models/querysets/#id4

我用了很多它似乎运作良好,那么你可以去coin_values.currency.name。

另外我不认为你需要做你的过滤器country = country.id,只是国家=国家,但我不知道有什么区别,而不是少打字。

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()