model manytomany - Django Queryset con filtro sulla chiave esterna inversa




one example (5)

Permettetemi di tradurre la risposta scritta di Spike in codici per i futuri spettatori. Tieni presente che ciascuna "Marca" può avere zero o più "MakeContent"

Se il richiedente significa interrogare "Crea" con ALMENO UNO "MakeContent", il cui testo è pubblicato = True, allora il secondo frammento di Jason Christa risponde alla domanda.

Lo snippet è equivalente a

makes = Make.objects.select_related().filter(makecontent__published=True).distinct()

Ma se il richiedente significa interrogare "Crea" con TUTTI i "MakeContent" di cui è stato pubblicato = True, quindi seguendo le "marche" sopra,

import operator
make_ids = [m.id for m in makes if 
    reduce(operator.and_, [c.published for c in m.makecontent_set.all()] ) 
]
makes_query = Make.objects.filter(id__in=make_ids)

contiene la query desiderata.

Ho il seguente modello Django:

class Make:
   name = models.CharField(max_length=200)

class MakeContent:
   make = models.ForeignKey(Make)
   published = models.BooleanField()

Mi piacerebbe sapere se è possibile (senza scrivere direttamente SQL) per generare un queryset che contenga tutti i Make e i relativi MakeContent relativi a dove è published = True .


So che questa è una domanda molto vecchia, ma sto rispondendo. Poiché penso che la mia risposta possa aiutare gli altri. Ho cambiato il modello un po 'come segue. Ho usato Django 1.8.

class Make(models.Model):
    name = models.CharField(max_length=200)

class MakeContent(models.Model):
        make = models.ForeignKey(Make, related_name='makecontent')
        published = models.BooleanField()

Ho usato il seguente queryset.

Make.objects.filter(makecontent__published=True)

Spero che ti sarà d'aiuto.


Django non supporta il metodo select_related () per le ricerche inverse di chiavi esterne, quindi il meglio che puoi fare senza lasciare Python sono due query di database. Il primo è quello di prendere tutti i Make che contengono MakeContents dove pubblicati = True, e il secondo è quello di prendere tutti i MakeContents dove pubblicati = True. È quindi necessario scorrere e organizzare i dati come desiderato. Ecco un buon articolo su come fare questo:

http://blog.roseman.org.uk/2010/01/11/django-patterns-part-2-efficient-reverse-lookups/


Sì, penso che tu voglia

make = Make.objects.get(pk=1)
make.make_content_set.filter(published=True)

o forse

make_ids = MakeContent.objects.filter(published=True).values_list('make_id', flat=True)
makes = Make.objects.filter(id__in=make_ids)

questo è un altro modo semplice per farlo.

Name.objects.exclude(alias=None)




django model filter django-queryset