如何过滤Django中没有任何指向它们的其他对象的对象?

时间:2014-12-03 11:42:15

标签: python django orm

我正在使用Django 1.7.1。

我有一组类似于以下结构的模型:

class Group(models.Model):
    name = models.CharField(max_length=50, unique=True)

class ItemTypeOne(models.Model):
    name = models.CharField(max_length=50, unique=True)
    ref = models.ForeignKey(Group)

class ItemTypeTwo(models.Model):
    name = models.CharField(max_length=50, unique=True)
    ref = models.ForeignKey(Group)

class ItemTypeThree(models.Model):
    name = models.CharField(max_length=50, unique=True)
    ref = models.ForeignKey(Group)

如上所述here我知道可以使用orm来过滤特定类对象未指向的对象。在我的情况下,它会是这样的:

filtered = Group.objects.exclude(itemtypeone__isnull=False,
                                 itemtypetwo__isnull=False,
                                 itemtypethree__isnull=False)

我的目标是使用orm获得相同的结果,而无需明确告知“反向关系”,类似于(伪代码跟随):

filtered = Group.objects.exclude(gereric_reverse_relations_exp__isnull=False)

这是否可以使用django orm来实现?

提前致谢! :)

1 个答案:

答案 0 :(得分:1)

您可以检查所有模型,找出哪些模型在Group上有外键并动态构建查询。使用模型的_meta get_all_related_objects()获取RelatedObject模型的Group列表:

>>> related = Group._meta.get_all_related_objects()
>>> print related 
[<RelatedObject: app:itemtypeone related to group>, <RelatedObject: app:itemtypetwo related to van>, <RelatedObject: app:itemtypethree related to group>]

然后构建您的查找:

>>> excludes = dict(("%s__isnull" % ro.get_accessor_name(), False) for ro in related)

执行查询:

>>> filtered = Group.objects.exclude(**excludes)

(警告:大多数未经测试的代码,可能需要一些调整)。