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

How optimize fetch and related objects loading?

我是 django 的初学者,在寻找解决方案几个小时后,我终于寻求帮助。我想用我的模型找到 retrieve/fetch 数据的最佳方式(性能)。我尝试了几件事,并阅读了有关 select_related、prefetch_related.

的文档

具体问题是:

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

我的模型:

我有一个产品与 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)

因此,正如我所说,我需要检索包含所有存储库、源和平台的产品列表。这是我在 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 秒才能显示结果。有没有一种方法可以简单地默认加载嵌套/相关对象?

感谢阅读,

嗯,我找到了解决我的问题的方法,我不需要迭代视图中的对象来加载它们。只需要在模板中创建一个查询集和访问。像这样:

在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 %}

就这些了...