Do Django backward relations add computational overhead?

Question:

In Django, you create models and can optionally specify a foreign key on a field

class Man:
      ...

class Dog:
      ...
      owner = models.ForeignKey(Man, on_delete=models.SET_NULL)

You can then query each Dog for its respective owner or get all dogs for a Man

owner = some_dog.owner

all_dogs = some_man.dog_set.all()

If you want to not create a backward relation as specified by the docs, you can do

class Man:
      ...

class Dog:
      ...
      owner = models.ForeignKey(Man, on_delete=models.SET_NULL, related_name='+')

Now you no longer have access to all_dogs = some_man.dog_set.all().

However, does this additional "building" of a backward relation add overhead? If I just never ever used all_dogs = some_man.dog_set.all() would it matter whether or not I had specified related_name='+' in Dog? Would it slow things down potentially?

And is this functionality purely implemented in application side Django, or would related_name='+' also change the database schema itself? Thank you, any insight would be greatly appreciated.

Asked By: AlanSTACK

||

Answers:

However, does this additional “building” of a backward relation add overhead?

No

If I just never ever used all_dogs = some_man.dog_set.all() would it matter whether or not I had specified related_name=’+’ in Dog? Would it slow things down potentially?

No, and no.

And is this functionality purely implemented in application side Django, or would related_name=’+’ also change the database schema itself?

It’s implemented with Python descriptors. In the case of ForeignKey, that’s a ReverseManyToOneDescriptor.
There is no change in the database schema, and the presence or absence of a related name does not generate a migration.

If you haven’t disabled the relation, you should actually see the descriptor objects there as attributes on the model classes. Something like this:

>>> Dog.owner
<django.db.models.fields.related_descriptors.ForwardManyToOneDescriptor at 0x105db25d0>
>>> Man.dog_set
<django.db.models.fields.related_descriptors.ReverseManyToOneDescriptor at 0x105db27d0>

These are the objects which make Django’s ORM magic work.

Answered By: wim
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.