Search code examples
djangoorm

Django: how select items that do not have referencies from other items?


Assume, we have a model:

class Critters(models.Model):
    name = models.CharField()
    parent = models.ForeignKey(Critters, blank=True, null=True, on_delete=models.CASCADE)

In begin was some critters:

id  Name      Parent
==  ========  ========
 0  Critter1
 1  Critter2
 2  Critter3

And then, some critters made a children:

id  Name      Parent
==  ========  ======
 0  Critter1
 1  Critter2
 2  Critter3
 3  Child1         0
 4  Child2         1

I wand make a request for select all parents without childrens (i.e. no creatures with parents, and no parents with existing childrens):

id  Name      Parent
==  ========  ======
 2  Critter3

I think it can be done with annotate and exact django's directives, but i'm dubt in stick how exactly i can make this...

UPDATE1 Ofcourse, critter and child in field Name just for example, we can't filter table by Name.


Solution

  • I think it can be done with annotate and exact django's directives.

    It can be done even simpler. You can filter with:

    Critters.objects.filter(parent=None, critters=None)

    We thus filter on the reversed relation. This is a LEFT OUTER JOIN and then check if that is None. It will thus make a query that looks like:

    SELECT *
    FROM critters
    LEFT OUTER JOIN critters AS c ON c.parent_id = critters.id
    WHERE parent_id IS NULL AND c.id IS NULL