Python / Django ORM按一个对象匹配的ManyToMany关系进行过滤

时间:2017-09-08 19:00:12

标签: python django filter orm manytomanyfield

我无法理解如何使用涉及ForeignKeys和ManyToMany字段的Django ORM进行过滤。我做了大量的谷歌搜索,但找不到类似的案例。 Django文档也没有多大帮助。

这是情况。我有应用程序。一个应用程序可以有多个版本。这些版本具有元数据,例如与它们兼容的平台版本。版本可以与多个平台版本兼容。我想找到与特定平台版本兼容的最新版本。

所以在Django中,我有一个App模型,我有一个Release模型,App是ForeignKey。我也有一个PlatformVersion模型。在Release模型中,我将PlatformVersion作为ManyToManyField。

我想在App模型上创建一个方法,它为我提供了与特定PlatformVersion兼容的最新版本。它也可以与其他PlatformVersions兼容,我不在乎。但它至少需要与那个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)

发布有多个PlatformVersions,因此我无法使用=运算符(platform_versions=a_single_platform_version)进行过滤。

我也不能使用__inplatform_versions__in=a_single_platform_version),因为这意味着“给我发布release.platform_versions的值在a_single_platform_version(列表)中的版本”。我想反过来说:“给我释放release.platform_versions(列表)包含a_single_platform_version的值”。

遗憾的是,

__contains仅用于字符串,而不是用于评估列表中是否存在值。我尝试使用Related Field got invalid lookup: contains时收到__contains错误。

我该怎么办?子查询?排除?我有一个过滤器吗?别的什么?谢谢!

1 个答案:

答案 0 :(得分:1)

  

发布有多个PlatformVersions,因此无法使用=进行过滤   operator(platform_versions = a_single_platform_version)。

这实际上是正确的方法,对多对多字段进行相等比较意味着必须存在指定值但允许其他值。