Django - 加入相关表的第一行

时间:2012-10-28 14:53:02

标签: django django-models django-queryset

假设我有表ProductsImages,其中产品可以包含许多图像。在为搜索结果页面提取产品列表时,如何将第一个产品图像包含为缩略图?

在考虑性能时,最好的方法是什么? (查询次数,内存,总时间等)

2 个答案:

答案 0 :(得分:0)

我相信你会想直接在模板中获取图像。而不是在视图中构建列表并将其传递给模板,因为会有多个项目。

所以我建议在Products模型中实现一个方法,找到第一个图像并返回它的URL。

models.py

def Products(models.Model):
    #your fields

    def get_image_url(self):
        try:
            img = self.images_set.filter()[0] #get first image
            return img.url()
        except Exception:
            return None

在模板中:

{% for p in product_list %}
     {# render product and add image #}
     <img href="{{p.get_image_url }}" />
{% endfor %}

答案 1 :(得分:0)

如果您需要通过大量架构重写来提升性能,那么去规范化是第一种尝试:

class Product(models.Model): # instead of Products as convention
    first_image = models.ImageField(editable=False, null=True)

然后在first_image通过信号更新时保持Product.image_set

此外,您甚至可以将“weakref”存储在某个转储字段中(当您真正需要它时使用它:)

class Product(models.Model):
    # from django-jsonfield, store raw values of ImageField of the Images model
    extra = JSONField()
    def first_image(self):
        image = self.extra.get('image')
        return models.ImageField.attr_class(None, models.ImageField(), image) if image else None

其他简单方法可能包括

  • 批量加载第一批图像,并按照Product()模板循环使用它们。需要标记第一批图像以便于查询。
  • 直接将first_image存储在Product中,而不是Images。这适用于没有太多管理要求的简单网站。