Django 如果存在,请从相关表中选择一条记录,否则返回None

Django 如果存在,请从相关表中选择一条记录,否则返回None,django,Django,我有两种型号: class Box(models.Model): class BoxImages(models.Model): box=models.ForeignKey(Box) img=models.ImageField() cover=models.IntegerField(default=0) 只有一个图像可以是盒子的封面图像,盒子可能根本没有任何图像。我现在想要的是得到盒子的列表以及它们的封面图片。但django使用内部连接,并带来只有相应封面

我有两种型号:

  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自己决定使用哪个连接,我如何强制它使用左连接或左外连接?

如果你想拥有所有的框,不管它们是否有封面图像,只需放下
过滤器即可。该过滤器有效地将查询集减少为仅包含封面图像的框

Box.objects.select_related('box_boximages').values('id','box_label', 'box_boximages__cover')
select_related
将在同一查询中获取相关的BoxImage(如果存在)。queryset将包含所有长方体对象,即使它们没有长方体图像

编辑:

它返回所有图像;该框显示5个项目,因为它有5张图片

是的,你说得对<代码>值
将根据fkey关系添加条目。有几种方法可以解决这个问题

(a) 最简单的方法是,不要使用
,而是简单地迭代queryset,并使用Box实例及其相关的boximage。代码将很容易理解。使用
select\u related
时,您还应该具备良好的性能

(b) 使用聚合仅获取作为封面的框图像。查看
aggregate
函数。您可以将其与
Exists
结合使用,以查找封面图像(或
Max

(c) 创建两个查询集,一个包含没有BoxImage的框,另一个使用BoxImage封面获取所有相关的框实例。把这两者结合起来

就我个人而言,我认为(a)是最简单的,因此在以后阅读代码或为其他开发人员阅读代码时最好理解


如果您总是根据封面与非封面图像进行选择,并且您可以自由更改模型,那么您可以考虑使用两个模型+模型继承并创建BoxCover(OneToNerelation到Box)和BoxImage(n:1到Box)模型。这将是最容易理解和处理的。

如果一个盒子有五个图像和一个封面图像,那么它不会在没有某种过滤器的情况下返回所有五个图像吗?让我试试。谢谢Risadinha…刚刚检查过。它返回所有图像;该框显示5个项目,因为它有5张图片。