如何优化获取和相关对象加载?

时间:2015-08-06 13:05:18

标签: python django-models fetch

我是django的初学者,经过几个小时的寻找解决方案,我终于寻求帮助了。我想找到用我的模型检索/获取数据的最佳方法(性能)。我尝试了几件事,并阅读了有关select_related,prefetch_related的文档。

具体问题是:

我有一个从Web服务检索到的specific_id列表,我需要加载相应的对象(按照列表给出的正确顺序)和一些相关的对象。

我的模特:

我有一个与0-N存储库相关的产品(来自存储库的FK)。 该产品还有0-N源(一对0-N传感器和0-N平台),通过sourcecontribtoproduct

class Product(models.Model):
    specific_id = models.CharField(max_length=100, unique=True, blank=False, null=False)
    shortname = models.CharField(max_length=100, unique=False, blank=True, null=False)

class Repository(models.Model):
    product = models.ForeignKey(Product, blank=True, null=True)
    name = models.CharField(max_length=200, unique=True, blank=False, null=False)
    url = models.CharField(max_length=2048, blank=True, null=True)

class SourceContribToProduct(models.Model):
    source = models.ForeignKey(Source)
    product = models.ForeignKey(Product)

class Source(models.Model):
    products = models.ManyToManyField(Product, through='SourceContribToProduct')
    shortname = models.CharField(max_length=100, unique=True, blank=False, null=False)
    platform = models.ForeignKey(Platform, blank=True, null=True)
    sensor = models.ForeignKey(Sensor, blank=True, null=True)

class Sensor(models.Model):
    shortname = models.CharField(max_length=50, unique=True, blank=False, null=False)
    type = models.TextField(blank=True, null=True)

class Platform(models.Model):
    shortname = models.CharField(max_length=50, unique=True, blank=False, null=False)
    description = models.TextField(blank=True, null=True)

因此,正如我所说,我需要检索一个包含所有Repository,Sources和Plateform的产品列表。这是我在views.py

中所做的
# Retrive list of objects
products = Product.objects.filter(specific_id__in=ids).prefetch_related('repository_set', 'source_set')
for p in products:
    p.repositories = p.repository_set.all()
    p.sources = Source.objects.filter(sourcecontribtoproduct__product_id=p.id).select_related('sensor_set', 'platform_set')
    for s in p.sources:
        s.sensor
        s.platform

# Sort the list
products = list(products)
products.sort(key=lambda t: ids.index(t.specific_id))

您如何看待此代码?我怎么能优化这种治疗,因为我觉得这太久了。我只有194个产品(最多5个存储库相关,不超过3个来源),我的浏览器需要大约5秒才能显示结果。有没有办法在默认情况下简单地加载嵌套/相关对象?

感谢阅读,

1 个答案:

答案 0 :(得分:0)

好吧,我发现了如何解决我的审讯,我不需要在视图中迭代对象来加载它们。只需要在模板中创建一个查询集和访问权限。像这样:

在view.py

products=Product.objects.filter(specific_id__in=ids).prefetch_related('repository_set', 'source_set').select_related('repository_set', 'source_set')

然后在我的模板中,迭代:

{% for src in product.source_set.all %}
   {{src.platform.shortname}} / {{src.sensor.shortname}}<br/>
{% endfor %}


{% for repo in product.repository_set.all %}
   {{repo.url}}%}
{% endfor %}

这就是......