无法检查queryset是否为子集

时间:2015-01-21 15:47:18

标签: django python-3.x django-models django-queryset django-1.7

我有三个模特

class Permission(models.Model):
    permission = models.CharField(max_length=255, null=False)

class PermissionMap(models.Model):
    name = models.CharField(max_length=255, null=False)
    origin = models.ForeignKey(Origin)
    license  = models.ForeignKey(License)
    class Meta:
        unique_together = (("origin", "license"),)


class PermissionValidatorMap(models.Model):
    permission_map = models.ForeignKey(PermissionMap)
    permission = models.ForeignKey(Permission)
    validator_set = models.ManyToManyField(ValidatorMetaData)
    class Meta:
        unique_together = (("permission_map", "permission"),)

现在我正在做的是获取origin,license,permission和validators_list(这是一个列表)并使用它们过滤PermissionValidatorMap

map=PermissionValidatorMap.objects.filter(permission_map__origin=origin,\
    permission_map__license=license, permission__permission=permission)

现在我想只过滤那些validator_set是一个子集或完全匹配的validators_list集合的那些 为此,我正在做这样的事情

map.filter(validator_set__in=validators_list)

但是这似乎不起作用,它似乎是单独检查validators_list的每个元素,因此返回重复的结果和 即使整个validator_set不是validator_list也会返回。

为了说明它的行为方式有点

[1,2,3]中的[a-> 1,2]将给出[a,a]

[2,3]中的[a-> 1,2]将给出[a]

在第一种情况下,它应该返回[a]而在第二种情况下不返回或为空 我该怎么做?

1 个答案:

答案 0 :(得分:1)

这是完全自然的行为。您的查询会在JOIN上生成ValidatorMetaData,并在PermissionValidatorMap与查询匹配的(PermissionValidatorMap, ValidatorMetaData)对中返回ValidatorMetaData。这里的关键是validator_set__in查找发生在ValidatorMetaData表中。

要获得所需的行为,您必须排除在PermissionValidatorMap中具有相关ValidatorMetaData 而非的每个validator_list,即:

PermissionValidatorMap.objects.exclude(
    validator_set__in=ValidatorMetaData.objects.exclude(id__in=validator_list))