-
-
Save jhgaylor/5873301 to your computer and use it in GitHub Desktop.
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) |
Oh God, I've been looking for this for 3 hours!
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 :)
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...
A.objects.filter(throughmodel__extra=True)
It does not work for version 4.0.5
Please help me
This post really helped me a lot! But I was still missing how to pull these through an API. So here is an example that builds upon yours that uses the many-to-many relationship of Books and Authors with the extra fields extra and external_url in ThroughModel we want to pull through an DRF endpoint. It also lists serializers, views and how things are connected. Hopefully others will find it useful despite the terrible naming :)
Assuming the data in the database looks like this:
Authors
Books
ThroughModel
This is how the models, serializers, and views all connect together.
models.py
serializers.py
views.py
Finally, this will give results that look like this:
query /api/authors/
query /api/books/