Django 选择原始请求中的相关内容

发布于 2025-01-06 04:29:37 字数 407 浏览 0 评论 0原文

如何进行“手动”select_lated 模仿以避免不良的数据库命中?

我们有:

class Country:
    name = CharField()
class City:
    country = models.ForeignKey(Country)
    name = models.CharField()

cities = City.objects.raw("select * from city inner join country on city.country_id = country.id where name = 'london'")

#this will hill hit DB
print cities[0].country.name

如何告诉 django 相关模型已被获取。

How to make "manual" select_related imitation to avoid undesirable DB hits?

we have:

class Country:
    name = CharField()
class City:
    country = models.ForeignKey(Country)
    name = models.CharField()

cities = City.objects.raw("select * from city inner join country on city.country_id = country.id where name = 'london'")

#this will hill hit DB
print cities[0].country.name

How to tell django that related models are already fetched.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眼波传意 2025-01-13 04:29:37

具有 prefetch_lated 的解决方案(这意味着将进行两次查询,1 个针对城市,1 个针对国家) em> 取自 django-users ,这不是一部分公共 API 的一部分,但正在使用 Django 1.7

from django.db.models.query import prefetch_related_objects
#raw querysets do not have len()
#thats why we need to evaluate them to list
cities = list(City.objects.raw("select * from city inner join country on city.country_id = country.id where name = 'london'"))
prefetch_related_objects(cities, ['country'])

更新

现在在 Django 1.10 prefetch_lated_objects 是公共 API 的一部分。

A solution with prefetch_related (this means that two queries will be made, 1 for the cities and 1 for the countries) taken from django-users which is not part of the public API but is working on Django 1.7

from django.db.models.query import prefetch_related_objects
#raw querysets do not have len()
#thats why we need to evaluate them to list
cities = list(City.objects.raw("select * from city inner join country on city.country_id = country.id where name = 'london'"))
prefetch_related_objects(cities, ['country'])

UPDATE

Now in Django 1.10 prefetch_related_objects is part of the public API.

长伴 2025-01-13 04:29:37

不确定您是否仍然需要这个,但我从阿拉斯代尔的答案开始解决了它。您希望使用查询中的信息来构建模型,否则当您尝试访问外键字段时,它仍然会触发其他查询。因此,在您的情况下,您需要:

    cities = list(City.objects.raw("""
        SELECT
            city.*, country.name as countryName
        FROM
            cities INNER JOIN country ON city.country_id = country.id
        WHERE
            city.name = 'LONDON"""))
    for city in cities:
        city.country = Country(name=city.countryName)

分配国家/地区的行不会访问数据库,它只是创建一个模型。之后,当您访问 city.country 时,它不会触发另一个数据库查询。

Not sure if you still need this, but I solved it starting with Alasdair's answer. You want to use the info from the query to build the model or it'll still fire additional queries when you try to access the foreign key field. So in your case, you'd want:

    cities = list(City.objects.raw("""
        SELECT
            city.*, country.name as countryName
        FROM
            cities INNER JOIN country ON city.country_id = country.id
        WHERE
            city.name = 'LONDON"""))
    for city in cities:
        city.country = Country(name=city.countryName)

The line that assigns the country doesn't hit the database, it's just creating a model. Then after that, when you access city.country it won't fire another database query.

吃素的狼 2025-01-13 04:29:37

我不确定你是否能做到这一点。作为替代方案,您可以从国家/地区表中选择各个字段并在每个实例上访问它们。

cities = City.objects.raw("select city.*, name as country_name from city inner join country on city.country_id = country.id where name = 'london'")

city = cities[0]
# this will not hit the database again
city.country_name

I'm not sure if you can do this. As an alternative, you can select individual fields from the country table and access them on each instance.

cities = City.objects.raw("select city.*, name as country_name from city inner join country on city.country_id = country.id where name = 'london'")

city = cities[0]
# this will not hit the database again
city.country_name
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文