Django Rest Framework,数据库查询优化
Posted
技术标签:
【中文标题】Django Rest Framework,数据库查询优化【英文标题】:Django Rest Framework, database queries optimization 【发布时间】:2018-10-23 18:56:25 【问题描述】:我刚开始使用 ORM 来执行我的数据库调用,我很难找到优化我的代码/查询的好方法。
我有可以在 ProductGroups 中的产品。产品可以有 0 到 n 个价格。价格由其 ActorLocation 及其值定义。 我想显示 ProductGroup 中所有产品的最低和最高价格。
我编写的代码可以运行,但由于数据库访问量大,运行速度非常慢。任何有助于朝着好的方向发展的帮助将不胜感激:)
型号:
class ProductGroup(OwnedClass):
name = models.CharField(max_length=200, blank=False)
class Product(models.Model):
name = models.CharField(max_length=200, blank=True)
internal_code = models.CharField(max_length=200, blank=True)
description = models.CharField(max_length=1000, blank=True)
product_group = models.ForeignKey(
ProductGroup, blank=True, null=True, on_delete=models.CASCADE)
class Price(models.Model):
price_without_taxes = models.FloatField(default=None, null=True)
location = models.ForeignKey(
ActorLocation, blank=True, null=True, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
class ActorLocation(models.Model):
name = models.CharField(max_length=200, blank=False, null=False)
这是我生成发送到我的 ProductGroupSerializer 的上下文的函数:
def get_context(product_groups):
locations = company.actor_locations.all()
for product_group in product_groups:
price_list = []
products = product_group.product_set.all()
for product in products:
for location in locations:
price = Price.objects.filter(product=product, location=location).last()
if price:
price_list.append(price.price_without_taxes)
if price_list:
context = 'lowest_product_price': round(min(price_list), 2), 'highest_product_price': round(max(price_list), 2)
else:
context = 'lowest_product_price': "", 'highest_product_price': ""
contexts[product_group.id] = context
return contexts
【问题讨论】:
看看 select_related() 和 prefetch_related() docs.djangoproject.com/en/2.0/ref/models/querysets/… 。另见docs.djangoproject.com/fr/2.0/topics/db/optimization/… 【参考方案1】:你可以试试aggregates-over-a-queryset,例如:
from django.db.models import Max, Min
locations = company.actor_locations.all()
Price.objects.annotate(
lowest_product_price=Min(price_without_taxes),
highest_product_price=Max(price_without_taxes)
).filter(
product__product_group__in=product_groups,
location__in=locations
).values(
'lowest_product_price', 'highest_product_price')
【讨论】:
感谢您的回答,我想知道如何让它在我的应用程序上运行,我会在完成后回复您 很高兴为您提供帮助!以上是关于Django Rest Framework,数据库查询优化的主要内容,如果未能解决你的问题,请参考以下文章
python django-rest-framework 3.3.3 更新嵌套序列化程序
Django:rest framework之分页(Pagination)
django rest framework接口怎么传参进行数据查询?
Python前后端分离开发Vue+Django REST framework实战_Django REST framework框架