1

我被困在一个复杂的查询上,试图使用 Django 的 ORM。

模型.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 对象来跟踪这一点。当我们创建非特殊版本时,它必须表明与 SpecialVersion 的兼容性。也就是说,从 compatible_from 指示的 SpecialVersion 开始。产品可能会在某个特殊版本中被弃用。

现在,我希望能够在给定特定 SpecialVersion 的情况下找到合适的产品。换句话说,我想获取所有 Product 对象,其中有一个可用的版本,其 SpecialVersion 低于我给定的 SpecialVersion。此外,产品的弃用 SpecialVersion 必须为 null,或者如果不为 null,则低于给定的 SpecialVersion。

TL;DR:选择所有产品,其中给定的 SpecialVersion 在产品中最低 compatible_from SpecialVersion 和已弃用的 SpecialVersion(如果存在)之间的范围内。

编辑:示例。

产品
编号 | 弃用
0 | 无
1 | 2

版本
号 | 珠三角 | 兼容
0 | 0 | 1
1 | 0 | 2
2 | 1 | 2

特殊版本
ID | 版本 | 0
| 空 | 1
1 | 空 | 2
2 | 空 | 3
3 | 空 | 4

查询与 SpecialVersion 的兼容性将不返回任何产品,因为没有任何产品具有指定低兼容性的版本。查询 compat w/SpecialVersion 将返回所有产品,因为它们都具有分别从 SpecialVersion id=1 和 id=2 开始的兼容性。最后,查询 compat w/SpecialVersion 将仅返回产品 id=0,因为尽管这两种产品的 SpecialVersion 兼容性足够低,但对于 SpecialVersions 及更高版本,第二个产品已被弃用。

4

2 回答 2

0

我相信您正在寻找的是Django Q Object。这允许您在查询中使用复杂的查找,例如“OR”语句。如果我正确理解了您的问题,那么类似的东西应该可以正常工作:

from django.db.models import Q
models.Product.objects.filter(Q(deprecated__isnull=True) | Q(version__compatible_from__order__lte=GIVENSPECIALVERSION)).all()

其中GIVENSPECIALVERSION是您从代码中其他地方收到的版本顺序。

于 2012-08-07T14:25:17.423 回答
0

这是我最终使用的:

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))
于 2012-08-07T16:15:08.333 回答