如何在Django中的extra()。values()调用中获取相关对象?

时间:2009-07-16 15:17:10

标签: django django-views

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

Django equivalent for count and group by

我在我的应用程序中所做的是显示我的数据库中可用于某个国家/地区的硬币类型和面值的列表,因此来自英国的硬币可能具有“1个最小值”或“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字段)。

最好的方法是什么?

3 个答案:

答案 0 :(得分: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()

答案 1 :(得分: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连接并不是非常罕见的,所以如果没有一个干净的方法,我会感到惊讶。

答案 2 :(得分:0)

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

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

另外我不认为你需要在你的过滤器中做country = country.id,只有country = country但是我不确定除了打字之外还有什么区别。