Django ORM m2m限制为1

时间:2013-02-02 23:08:55

标签: django django-orm

# models.py
class Gallery(models.Model):
    images = models.ManyToManyField(Image, null=True, blank=True)

class Image(models.Model):
    image = models.ImageField()


# views.py
class GalleryIndex(ListView):
    model = Gallery

我需要为每个画廊获取缩略图,这是它的第一个/最后一个/任何图像。 如何在不调用第二个SQL查询的情况下,将任何图库的图像限制为1作为自定义属性(不覆盖Gallery.images)?

3 个答案:

答案 0 :(得分:0)

多对多充当普通查询集的描述符,因此您可以my_gallery.images.all()[0]将查询限制为1。

答案 1 :(得分:0)

我不认为我理解你想做什么,但下面的代码不适合你?

class Gallery(models.Model):
    images = models.ManyToManyField(Image, null=True, blank=True)

    def get_thumb(self):
        return self.images.all()[0]

或许还有其他概念:

class Gallery(models.Model):
    images = models.ManyToManyField(Image, null=True, blank=True)
    thumbnail = models.ImageField()

    def save(self, *args, **kwargs):
        self.thumbnail = self.images.all()[0].image

(虽然这里需要一些例外)

答案 2 :(得分:0)

我应该更好地阅读文档。标准QuerySet API无法有效处理此类情况(annotate()为每个父字段生成GROUP BY子句很慢)所以我使用extra()方法和原始子查询。

class GalleryIndex(ListView):
    queryset = Gallery.objects.extra(select={'thumb':
        """
        SELECT "image"
        FROM "app_image", "app_gallery_images"
        WHERE (
            "app_gallery"."id" = "app_gallery_images"."gallery_id"
            AND "app_gallery_images"."image_id" = "app_image"."id"
        )
        AND "app_image"."image" IS NOT NULL
        LIMIT 1
        """
    })

此查询集完全符合我的要求,因为SorlImageField(和ImageField)只需要文件名来表示模板中的缩略图。