1

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オブジェクトを作成することにより、これを追跡します。非特別バージョンを作成するときは、SpecialVersionとの互換性を示す必要があります。つまり、compatible_fromで示されるSpecialVersionから開始します。製品は、特定の特別なバージョンで非推奨になる可能性があります。

今、私は特定のSpecialVersionを与えられた適切な製品を見つけられるようにしたいと思います。つまり、指定されたSpecialVersionの下にSpecialVersionがあるバージョンが利用可能なすべてのProductオブジェクトを取得したいと思います。さらに、製品の非推奨のSpecialVersionはnullであるか、nullでない場合は指定されたSpecialVersionより下である必要があります。

TL; DR:指定されたSpecialVersionが製品の最も低いcompatibility_from SpecialVersionと非推奨のSpecialVersion(存在する場合)の間の範囲にあるすべての製品を選択します。

編集:例。

製品
ID| 非推奨の
0| なし
1| 2

バージョン
ID| prd | compat
0 | 0 | 1
1 | 0 | 2
2 | 1 | 2

SpecialVersions
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互換性が十分に低いにもかかわらず、2番目の製品がSpecialVersions以降で非推奨になっているためです。

4

2 に答える 2

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 に答える
0

あなたが探しているのはDjangoQオブジェクトだと思います。これにより、クエリで「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 に答える