python – 从queryset构建最高价格列表的最有效方法?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 从queryset构建最高价格列表的最有效方法?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2045字,纯文字阅读大概需要3分钟。
内容图文
![python – 从queryset构建最高价格列表的最有效方法?](/upload/InfoBanner/zyjiaocheng/774/e761c32906434c67b63ebaeed614c2b2.jpg)
在我的应用程序的一个页面中,我试图为每个公司展示最昂贵的汽车.我的模型大致如下:
class Company(models.Model):
id = models.IntegerField(primary_key=True)
company = models.CharField(max_length=100)
headcount = models.IntegerField(null=False)
info = models.CharField(max_length=100)
class Car(models.Model):
id = models.IntegerField(primary_key=True)
company_unique = models.ForeignKey(Company)
company = models.CharField(max_length=50)
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=9, decimal_places=2, default=0.00)
所以,我想建立一个包含每个公司最昂贵的Car对象的列表.
我这样解决了这个问题:
company_list = Company.objects.all()
most_expensive = []
for company in company_list:
most_expensive.append(Car.objects.filter(company_unique=company.id).order_by("-price")[0])
然而,这似乎是一种非常低效的方法.我可以看到Django Debug Toolbar这个代码正在制作太多的mysql查询.
有人可以建议一个更好的方法来构建这个列表,可能只是一次或两次命中MySQL吗?
解决方法:
虽然你正在处理的是一个很常见的情况,但显而易见的解决方案似乎缺乏.
解决方案1,发现于this article.您可以尝试以下这些方面:
companies = Company.objects.annotate(max_price=Max('car__price'))
values = tuple((company.id, company.max_price) for company in companies)
expensive_cars = Car.objects.extra(where=['(company_unique_id, price) IN %s' % (values,)])
不能说我喜欢解决方案 – 应该避免使用.extra – 但我想不出更好的方法.我也不完全确定它会起作用.
解决方案2,次优.你可以使用custom Prefetch object.
prefetch = Prefetch('cars', queryset=Car.objects.order_by('-price'), to_attr='cars_by_price')
companies = Company.objects.prefetch_related(prefetch)
most_expensive_cars = []
for company in companies:
most_expensive_cars.append(list(company.cars_by_price.all())[0])
这绝对可以工作并在两个查询中获取所有内容,但是非常浪费,因为它会将与给定公司集相关的所有汽车加载到内存中.请注意,list()部分不是可选的:无论您采用切片还是索引,都会复制查询集并生成单独的数据库查询,从而否定预取,而实例化列表将使用所述预取的结果.
如果您之后需要访问公司,例如Car.company,请不要回避使用select_related,正如Erik在评论中所建议的那样.
内容总结
以上是互联网集市为您收集整理的python – 从queryset构建最高价格列表的最有效方法?全部内容,希望文章能够帮你解决python – 从queryset构建最高价格列表的最有效方法?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。