Skip to content

Instantly share code, notes, and snippets.

@jhgaylor
Last active September 24, 2024 10:11
Show Gist options
  • Save jhgaylor/5873301 to your computer and use it in GitHub Desktop.
Save jhgaylor/5873301 to your computer and use it in GitHub Desktop.
Example of using a through model in Django and filtering by a value on the custom through model.
class A(models.Model):
things = models.ManyToManyField("B", through=ThroughModel)
class B(models.Model):
text = models.TextField()
class ThroughModel(models.Model):
a = models.ForeignKey(A)
b = models.ForeignKey(B)
extra = models.BooleanField()
#this will return a list of ThroughModel objects
ThroughModel.objects.filter(b=instance_of_b, extra=True)
#this will return a list of A objects based on an extra field on the through table
A.objects.filter(things__ThroughModel__extra=True)
#keep in mind that limiting by one of the foreign keys on the through model is easier
A.objects.filter(things=instance_of_b)
@jhgaylor
Copy link
Author

I am glad that people have been able to comment on this to keep it up to date. I had no idea it would still be helping people years later. I am glad it was helpful :)

@hepcat72
Copy link

hepcat72 commented Mar 11, 2022

Someone told me on stack that if all you have is:

class A(models.Model):
    things = models.ManyToManyField("B")
class B(models.Model):
    text = models.TextField()

(i.e. no extra fields for the relationship), there was a syntax to use in A.objects.filter(...) to reference the "hidden" through model, in the corresponding way that it can be accessed using:

qs = A.things.through.objects.filter(Q(b__text__icontains="whatever"))

^^^ I know the above works without defining through. I've tried it multiple times as I was trying to work all this out. But I was unable to find a corresponding way off the A model directly, such as:

qs = A.objects.filter(things__b__text__icontains="whatever")

^^^ which is wrong. So does there exist a way to reference the hidden through model in the filter expression from the class containing the M:M relationship (without explicitly defining through)? I don't think there is, but you guys seem to know this topic well, so I suspect someone here knows...

I'm just curious. I figured out how to do what I wanted to do and learned a lot about all this, but I'm just wondering if the suggestion I received on stack was wrong - or whether I just couldn't figure it out...

@linhfishCR7
Copy link

linhfishCR7 commented Dec 18, 2022

A.objects.filter(throughmodel__extra=True)
It does not work for version 4.0.5
Please help me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment