Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
复杂查询(django ORM或SQL)_Sql_Django_Orm - Fatal编程技术网

复杂查询(django ORM或SQL)

复杂查询(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

我被困在一个复杂的查询中,试图使用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(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啊,明白了。试着把我的头绕在你的设置上。很高兴你成功了!是的,有点复杂。谢谢