Skip to content
Advertisement

Django query self referencing queryset

I have a model Thing that is self referencing. The relation copied_from is being used to save the Thing-Object that the current Thing-Object was copied from. Here is my Model:

class Thing(models.Model):
    copied_from = models.ForeignKey("Thing", related_name="copies", null=True, default=None, on_delete=models.SET_NULL)
    collection = models.ForeignKey(Collection, ...)
    ...    
    

What I would like to achieve is to get all Things from a collection that have no been copied. I was thinking about using unionto take all Things and “substract” all things that have been copied. The issue is that in my solution I had to iterate over the Queryset where copied_from__is_null=False to get the ids of Things that have been used to create a copy. This is of course not a good solution.

Advertisement

Answer

You can filter with:

Thing.objects.filter(copied_from=None)

This will thus retrieve all Things where the copied_from is None.

If you want to retrieve all Things that are no copies, and have not been copied from, you can work with:

Thing.objects.filter(copied_from=None, copies=None)

or if you want to retrieve Things for which no Thing exists that is a copy from that, you can work with:

Thing.objects.filter(copies=None)

This works since we perform a LEFT OUTER JOIN on the Thing table, and only retrieve Things fro which the LEFT OUTER JOIN is NULL.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement