And*_*rew 14 django orm django-models
如何制作"手动"select_related模仿以避免不良的数据库命中?
我们有:
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
Run Code Online (Sandbox Code Playgroud)
如何告诉django相关模型已经被提取.
Tod*_*dor 11
从django-users获取的解决方案prefetch_related (这意味着将进行两次查询,1次为1 cities和1 countries),这不是公共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'])
Run Code Online (Sandbox Code Playgroud)
UPDATE
现在在Django 1.10中prefetch_related_objects是公共API的一部分.
小智 8
不确定你是否仍然需要这个,但我从Alasdair的答案开始解决了这个问题.您希望使用查询中的信息来构建模型,或者在尝试访问外键字段时仍然会触发其他查询.所以在你的情况下,你想要:
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)
Run Code Online (Sandbox Code Playgroud)
分配国家/地区的行不会访问数据库,它只是创建模型.然后,在您访问city.country它之后,将不会触发另一个数据库查询.
我不确定你是否能做到这一点。作为替代方案,您可以从国家/地区表中选择各个字段并在每个实例上访问它们。
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4187 次 |
| 最近记录: |