通过自我关系过滤对象

时间:2018-06-14 09:35:55

标签: django django-models

这是我的Django模型:

class Message(models.Model):
    text = models.TextField()
    parent = models.ForeignKey('Message', null=True, on_delete=models.SET_NULL)
    threads = ThreadManager()


class ThreadManager(models.Manager):
    def get_queryset(self):
        return super(ThreadManager, self).get_queryset().filter()

如您所见,它使用自定义管理器。在ThreadManager我想过滤具有自我关系的消息。我的意思是parent指的是它的记录。 (x.parent = x

如何写filter?它有可能吗?

1 个答案:

答案 0 :(得分:2)

自我参考

您可以使用过滤器来处理pk列:

from django.db.models import F

Message.objects.filter(parent=F('pk'))

所以在这里我们指定parent_id应该与主键相同,因此在这种情况下,关系是循环的。

请注意,此过滤器将检测长度超过1的周期。例如,如果我们有两条消息AB,以及{{1} }和A.parent = B,然后此过滤器将检测到这一点。它仅检测B.parent = A。{/ p>所在的Message

此外,Django 执行语义检查:如果您稍后让A.parent == A引用另一个模型,则此过滤器不再有意义,但Django不会产生警告。

非自我引用

如果我们想要相反,我们可以使用parent或将其包装到.exclude(..)对象中:

Q

因此,在这种情况下,# using exclude Message.objects.exclude(parent=F('pk')) # using Q from django.db.models import Q Message.objects.filter(~Q(parent=F('pk')))要么没有父级,要么父级不是同一个消息。