2

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

Kobz
  • 469
  • 6
  • 17

1 Answers1

4
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.

Kevin Christopher Henry
  • 46,175
  • 7
  • 116
  • 102
  • That's it, I'm trying to create a ManyToMany relationship but with extra arguments. I wasn't aware that you could add some extra attribute with through model. I'll try that, it will be easier I think. Thanks ! – Kobz Feb 27 '14 at 10:48
  • @Kobz: When you declare a foreign key from `B` to `A`, Django lets you query on the reverse relationship (from `A` to `B`) as well. See the docs on [Lookups that span relationships](https://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships). I highly recommend you re-read the docs and tutorial thoroughly or else you're likely to experience a lot of confusion. – Kevin Christopher Henry Feb 27 '14 at 10:55
  • I'll do that. I started using django on a not fully 'unoptimized' way (adding queries which weren't necessary) and now I'm trying to do some clean code using as much as possible Django features and there are some concepts that I don't master yet. Thanks for your help, you were very helpful to me :) – Kobz Feb 27 '14 at 11:22