2013-02-02 45 views
0
# 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查询的情况下将任何图库的图像限制为自定义属性(不覆盖Gallery.images)?Django ORM m2m限制为1

回答

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的)只需要文件名来表示模板的缩略图。

0

一个多一对多作为一个正常的查询集的描述符,所以你可以做my_gallery.images.all()[0]限制查询到1

+0

这只适用于每个画廊,但不适用于所有人......我错了吗? – mktums

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 

(有些异常醒目这里虽然需要)

+0

我想在单个SQL查询中选择图库和它们的第一张图像作为它们的自定义属性。 第一个示例仍然生成一个+ N个查询(其中N是库的数量)。 第二个例子不能存在于我的情况,因为缩略图选择的自定义逻辑... – mktums

+0

因此,描述您的自定义缩略图选择... – aherok

+0

它甚至不是选择,而是填充'Image'和'Gallery'模型是完全独立和分离的(这就是为什么'图像'字段可以为空)。 我通过提供'queryset = Gallery.objects.prefetch_related('images')。all()'来查看类...但是仍然是2个查询,而不是一个。 – mktums