Home > Software design >  Accessing the "many" side from the "one" side effectively
Accessing the "many" side from the "one" side effectively

Time:02-19

Considering the following models:

class ManySide(django.db.models.Model):
    one_side = models.ForeignKey(
        to=OneSide, on_delete=models.PROTECT, related_name="related_one_side"
    )

class OneSide(django.db.models:model):
    # not containing any field relevant here

    def many_side_elements(self):
        pass # ?

What should I include in method many_side_elements so that calling it from a OneSide Model instance would list a queryset of ManySide elements?

Official docs imply that given o is a OneSide isntance, o.many_side_set.all() should work but it returns an error in shell.

My current solution is the following:

from django.apps import apps

[...]

def many_side_elements(self):
    ManySideModel = apps.get_model('<app_name_here>', 'ManySide')

    val = ManySideModel.objects.filter(one_side=self)

But I'm concerned it's ineffective since it requires importing the other Model. Actually it caused a circular dependency error message in my project, hence the get_model usage.

Is there any better way? Or xy_set should work in the first place? Then what am I doing wrong?

CodePudding user response:

If you create the model field with a related name, the related name overrides the _set queryset.

In your case o.related_one_side.all() should work without the need for another def.

See: https://docs.djangoproject.com/en/4.0/topics/db/queries/#following-relationships-backward

You can override the FOO_set name by setting the related_name parameter in the ForeignKey definition. For example, if the Entry model was altered to blog = ForeignKey(Blog, on_delete=models.CASCADE, related_name='entries'), the above example code would look like this: b.entries.all()

  • Related