复杂查询(django ORM或SQL)
我被困在一个复杂的查询中,试图使用Django的ORM models.py复杂查询(django ORM或SQL),sql,django,orm,Sql,Django,Orm,我被困在一个复杂的查询中,试图使用Django的ORM models.py class Product(models.Model): deprecated = models.ForeignKey(SpecialVersion, null=True) class Version(models.Model): compatible_from = models.ForeignKey(SpecialVersion) product = models.ForeignKey(Pro
class Product(models.Model):
deprecated = models.ForeignKey(SpecialVersion, null=True)
class Version(models.Model):
compatible_from = models.ForeignKey(SpecialVersion)
product = models.ForeignKey(Product)
class SpecialVersion(models.Model):
version = models.ForeignKey(Version, null=True)
order = models.IntegerField()
其要点是,产品有多个版本。其中一些版本是“特殊的”——我们通过创建一个指向“特殊”版本对象的SpecialVersion对象来跟踪这一点。当我们创建一个非特殊版本时,它必须表明与特殊版本的兼容性。也就是说,从compatible_from指示的SpecialVersion开始。在特定的特殊版本中,产品可能会被弃用
现在,我希望能够找到适当的产品给予一定的特殊版本。换句话说,我希望获得所有产品对象,其中有一个版本在我给定的SpecialVersion下具有SpecialVersion。此外,产品不推荐的SpecialVersion必须为null,如果不为null,则必须低于给定的SpecialVersion
TL;博士:
选择给定SpecialVersion介于产品中SpecialVersion的最低兼容_和不推荐的SpecialVersion(如果存在)之间的所有产品
编辑:示例
产品id|已弃用
0|无
1 | 2
版本
id | prd | compat
0 | 0 | 1
1 | 0 | 2
2 | 1 | 2
特殊版本
id | ver | ord
0 |空| 1
1 |空| 2
2 |空| 3
3 |空| 4
带有/SpecialVersion的兼容性查询将不会返回任何产品,因为没有任何产品的版本指定了如此低的兼容性。查询compat w/SpecialVersion将返回所有产品,因为它们的兼容性分别从SpecialVersion id=1和id=2开始。最后,对compat w/SpecialVersion的查询将只返回产品id=0,因为尽管这两种产品的SpecialVersion compat都足够低,但第二种产品已不推荐用于SpecialVersions及以上版本。我相信您正在寻找的是。这允许您在查询中使用复杂的查找,例如“OR”语句。如果我正确理解了你的问题,那么类似于这一点的东西应该可以很好地发挥作用:
from django.db.models import Q
models.Product.objects.filter(Q(deprecated__isnull=True) | Q(version__compatible_from__order__lte=GIVENSPECIALVERSION)).all()
其中GIVENSPECIALVERSION是您从代码中的其他地方收到的版本顺序。以下是我最后使用的:
products = Product.objects.annotate(min_version=Min(version_set__compatible_from__order)).filter(min_version__lte = given_special_version).filter(Q(deprecated__isnull = True) | Q(deprecated__order__gt = given_special_version))
您能否提供一些虚假数据,并根据示例请求显示您希望选择的行?我让SpecialVersions有一个空版本字段,因为这一点无关紧要。请关闭,但不完全关闭-我需要检查是否存在弃用(即-如果不为空,请确保我低于弃用的版本)。此外,没有版本字段-它是一个foreignkey,所以您只获得需要注释的版本集。请看下面我的答案。@guy who needsahand啊,明白了。试着把我的头绕在你的设置上。很高兴你成功了!是的,有点复杂。谢谢