Search code examples
djangoorm

Django queryset retrieve many-to-many choosen field values


I have a class A(Aid,Aname,manytomanyfield) with a many to many relationship to a class B(Bid,Bname).

I have for example three rows in A :
Aid,Aname
1,foo
2,bar
3,baz

I have for example three rows in B:
Bid,Bname
1,foo
2,bar
3,baz

With Django ORM I don't really see the relationship class which contains for example:
Aid,Bid
1,1
1,2
1,3
2,2
2,3

I want all A rows that match for example class B "3,baz" row.

In django "A.objects.filter(manytomanyfield=B.get(Bname=baz))":
Aid,Aname,Bname
1,foo,baz

Is there a way to retrieve all possible values of A relationship with B after filtering?
I want:
Aid,Aname,Bname,manytomanyfield
1,foo,baz,"foo,bar,baz"

I'm looking for a ",".join(B.values_list("Bname", flat=True) for example in "manytomanyfield".

In django admin, django produce this result with a new request for every line of the html table. I wonder if we can do this with only one ORM request.

Sorry for my english!

Update : I think there is a solution with django orm ExpressionWrapper, F function but I made a new field which stores in cache "foo,bar,baz" so there is only one request to retrieve my objects with their many to many relations.


Solution

  • You can .filter(…) [Django-doc] with:

    A.objects.filter(manytomanyfield__Bname='baz')

    this can retrieve the same A multiple times if the A is linked multiple times to a B named baz or if there are multiple B models with name='baz', you can add .distinct() [Django-doc] to retrieve each A at most once:

    A.objects.filter(manytomanyfield__Bname='baz').distinct()

    You can retrieve the related Bs with some_a.manytomanyfield.all(), so:

    qs = A.objects.filter(manytomanyfield__Bname='baz').prefetch_related('manytomanyfield').distinct()
    
    for a in qs:
        print(a.manytomanyfield.all())