Efficient way of dividing a querySet with a filter, while keeping all data?

Viewed 106

I have a 'Parts' model, and these parts are either linked to a 'Device' model or not yet. The actual "link" is done via more than just one ForeignKey, i.e. I have to go through 3 or 4 Models all linked between each other with ForeignKeys to finally get the data I want.

My question is: What is the most efficient way of getting both the linked and non-linked parts ?

Right now, I am getting all parts and simply outputting that, but I would like a little separation:

allParts = Parts.object.all()

I know I could do something similar to this:

allParts = Parts.object.all()
linkedParts = allParts.objects.filter(...device_id=id)
nonLinkedParts = allParts.objects.exclude(...device_id__in=[o.id for o in linkedParts])

But is that really the most efficient solution ? I feel like there would be a better way, but I have not yet found anything in the docs about it.

Just to clarify, there are only linked, and non-linked parts. These are mutually exclusive and exhaustive.

Thank you very much

1 Answers

If you are only interested in obtaining the elements, for example to iterate over it, you can work with two lists:

allParts = Parts.object.all()
linkedParts = []
nonLinkedParts = []

for part in allParts:
    if part.device_id == id:
        linkedParts.append(part)
    else:
        nonLinkedParts.append(part)

since these are lists, you can no longer (efficiently) filter further, or order by a specific condition. If you want to order it by a certain field, you should do that already in the allParts database query.

Related