【问题标题】:How do I get the related objects In an extra().values() call in Django?如何在 Django 的 extra().values() 调用中获取相关对象?
【发布时间】:2010-11-11 10:07:24
【问题描述】:

感谢这篇文章,我能够轻松地在 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 字段)。

最好的方法是什么?

【问题讨论】:

    标签: django django-views


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      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 查询集语言来表达该确切查询,我很想知道。我想带有计数和按两列分组的 SQL 连接并不是非常罕见,所以如果没有干净的方法,我会感到惊讶。

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2021-10-15
          • 2021-07-10
          • 2015-02-28
          • 1970-01-01
          • 2013-08-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-08
          相关资源
          最近更新 更多