我是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秒才能显示结果。有没有办法在默认情况下简单地加载嵌套/相关对象?
感谢阅读,
答案 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 %}
这就是......