我有两个模型:
class Box(models.Model):
class BoxImages(models.Model):
box=models.ForeignKey(Box)
img=models.ImageField()
cover=models.IntegerField(default=0)
只有一个图像可以是一个框的封面图像,一个框可能根本没有任何图像。我现在想要的是获取方框列表及其封面图片。但是django使用内连接并带来只有相应封面图像的盒子。
Box.objects.filter(box_boximages__cover=1).values('id','box_label')
我如何强制它使用左连接或左外连接,因为我读了ORM自己决定使用哪个连接?
答案 0 :(得分:1)
如果您想拥有所有方框,无论是否有封面图片,只需放下filter
即可。过滤器有效地将您的查询集减少到仅具有封面图像的Box。
Box.objects.select_related('box_boximages').values('id','box_label', 'box_boximages__cover')
select_related
将在同一查询中获取相关的BoxImages(如果存在)。查询集将包含所有Box对象,即使它们没有BoxImages。
编辑:
它返回所有图像;该框显示5项,因为它有5张图片。
是的,你是对的。 values
将为每个fkey关系添加条目。有几种方法可以解决这个问题。
(a)最简单的是,不使用values
,而是简单地遍历查询集并使用Box实例及其相关的BoxImages。代码很容易理解。使用select_related
,你也应该表现得很好。
(b)使用聚合来仅获取封面的盒子图像。看看aggregate
函数。您可以将其与Exists
结合使用,以查找封面图片(或Max
)。
(c)创建两个QuerySet,一个使用Boxes而不使用BoxImages,另一个使用BoxImage Covers获取所有相关的Box实例。结合这两个。
就我个人而言,我认为(a)是最简单的,因此最好在以后阅读代码或其他开发人员时理解。
如果您最终选择基于封面而不是封面图像和,您可以自由更改模型,那么您可以考虑使用两个模型+模型继承并创建BoxCover( OneToOneRelation to Box)和BoxImage(n:1 to Box)模型。这将是最容易理解和处理的。