Search code examples
djangodjango-querysetdjango-select-related

filter with select_related on Django


I have a problem with the usage of select_related feature of Django with the filter operation, here's my problem, I have three classes :

class A:
   # various fields here

class B(models.model):
   related_A = models.ForeignKey(A)
   related_C = models.ForeignKey(C)
   attribute1 = models.CharField(..)
   # Other attributes

class C(models.model):
   # Attributes

What I'm trying to do is, getting class A by filtering on class B on the key related_C according to another parameter attribute1 (from class B). To illustrate it properly, I have a function get_class_A(self) in my class C

get_class_A(self,param):
   classes_B = B.objects.filter(related_C = self,attribute1 = param)

It returns a QuerySet of classes B. What I want to do is to follow the ForeignKey pointing to A in order to transform this QuerySet of B into a list of objects A.

I tried various things such as :

classes_A = B.objects.select_related('A').filter(related_C = self, attribute1 = param)

and some variations but nothing worked. Does anyone knows how to do this ?

Thanks


Solution

  • def get_class_A(self, param):
        return A.objects.filter(b__related_c=self, b__attribute1=param).distinct()
    

    What you've described looks a lot like a ManyToMany relationship between A and C. If you declare it as such, and include your extra attributes by specifying B as a through model, Django will create the relationship between A and C for you.

    Also, select_related() has nothing to do with filtering results, it's just a tool that can allow you to reduce the number of database queries. From the docs:

    This is a performance booster which results in a single more complex query but means later use of foreign-key relationships won’t require database queries.