【问题标题】:Django - Join first row of a related tableDjango - 加入相关表的第一行
【发布时间】:2012-10-28 14:53:02
【问题描述】:

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

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

【问题讨论】:

    标签: django django-models django-queryset


    【解决方案1】:

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

    所以我会建议在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 %}
    

    【讨论】:

    • 这样会导致查询量比较大吗?
    【解决方案2】:

    如果您需要在不进行大量架构改造的情况下提升性能,则反规范化是第一种尝试方法:

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

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

    此外,您甚至可以将“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。这适用于没有太多管理要求的简单网站。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-26
      • 1970-01-01
      • 2021-12-07
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多