2017-09-08 3 views
0

ForeignKeysとManyToManyフィールドが含まれているDjango ORMを使用してフィルターをかける方法を頭で囲むことはできません。私はグーグルで何度もやったことがありますが、似たようなケースは見つけられません。 Djangoのドキュメントはあまり役に立ちません。Python/DjangoのORMフィルターby ManyToMany 1つのオブジェクトが一致する場所

ここに状況があります。私はアプリを持っています。アプリは複数のリリースを持つことができます。これらのリリースには、互換性のあるプラットフォームのバージョンなどのメタデータが含まれています。リリースは複数のプラットフォームのバージョンと互換性があります。特定のプラットフォームのバージョンと互換性のある最新のリリースを探したい。

Djangoでは、私はAppモデルを持っていて、AppはForeignKeyであるReleaseモデルを持っています。私はまた、PlatformVersionモデルを持っています。 Releaseモデルでは、PlatformVersionをManyToManyFieldとして持っています。

特定のPlatformVersionと互換性のある最新リリースを提供するAppモデルでメソッドを作成したいと思います。それは他のPlatformVersionsとも互換性があります。私は気にしません。しかし、少なくとも1つのPlatformVersionと互換性がある必要があります。

ここにいくつかのコードです:

class App(models.Model): 

    def get_latest_filtered_release(self, **kwargs): 
     platform_version = PlatformVersion.objects.get(name=kwargs.get('platform_version', None) 

     return self.releases.filter(platform_versions__in=platform_version).latest() 
     # When I try to run this I get "TypeError: 'PlatformVersion' object is not iterable" as expected 


class Release(models.Model): 

    class Meta: 
     ordering = ['-created_datetime'] 
     get_latest_by = 'created_datetime' 

    app = models.ForeignKey(App, related_name='releases') 
    platform_versions = models.ManyToManyField('PlatformVersion', related_name="platform_versions") 
    created_datetime = models.DateTimeField(auto_now_add=True) 


class PlatformVersion(models.Model): 

    name = models.CharField(unique=True) 

私は=演算子(platform_versions=a_single_platform_version)を使用してフィルタリングすることができませんので、リリースが複数のPlatformVersionsを持っているが。

これは、「release.platform_versionsの値がa_single_platform_version(リスト)にあるリリースを許可する」という意味で、__inplatform_versions__in=a_single_platform_version)のいずれも使用できません。私はその逆を望んでいます: "release.platform_versions(リスト)にa_single_platform_versionの値が入っているところで私にリリースしてください"。

__containsは残念ながら文字列のためだけであり、値がリストに存在するかどうかを評価するためではありません。 __containsを使用しようとすると、Related Field got invalid lookup: containsエラーが発生します。

私は何をしますか?サブクエリ?除外しますか?私は行方不明のフィルターがありますか?他に何か?ありがとう!

答えて

1

リリースに複数のPlatformVersionsが含まれているため、= 演算子(platform_versions = a_single_platform_version)を使用してフィルタリングできません。

実際にはこれを行う正しい方法です。多対多フィールドの等価比較は、指定された値が存在する必要がありますが、他の値を許可することを意味します。

+0

ありがとうございました!それは完全に動作します!私はそれをしないと仮定するのではなく、試してみたはずです。また、platform_versions__in = [a_single_platform_version]も動作します – Heather

+0

後者の式は、チェックするバージョンの数がクエリごとに異なる場合を含め、複数のバージョンをチェックしたい場合に便利です。 –

関連する問題