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 union
to 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 Thing
s where the copied_from
is None
.
If you want to retrieve all Thing
s 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 Thing
s 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 Thing
s fro which the LEFT OUTER JOIN
is NULL
.