2 votes

Django - Queryset couvrant les relations nulles en utilisant Q

Examinez les modèles :

#Models
class A(models.Model):
    fieldOfA = models.CharField(max_length = 4)
class B(models.Model):
    fieldOfB = models.CharField(max_length = 4)
class C(models.Model):
    classA = models.ForeignKey(A, blank=True, null=True)
    classB = models.ForeignKey(B, blank=True, null=True)

Lorsque je crée des objets de C, je m'assure qu'un objet a SOIT une relation de classeA, soit une relation de classeB.

Je cherche un seul ensemble de questions qui me permette d'obtenir des objets de C pour des valeurs spécifiques de fieldOfA ou de fieldOfB.

J'ai essayé, mais cela n'a pas fonctionné (le système renvoie [], bien qu'il y ait des résultats valides).

#Views - assume double underscore in the query
from django.db.models import Q
my_query = C.objects.filter(Q(classA _ _isnull = False, classA _ _fieldOfA = 'foo') | Q(classB _ _isnull = False, classB _ _fieldOfB = 'foo'))

Le problème que je vois est le "|" qui est appliqué. Deux querysets différents pour classA et classB fonctionnent bien. Y a-t-il un moyen d'appliquer un seul queryset pour que cela fonctionne ? Ou pire, un moyen de fusionner les querysets individuels.

2voto

ironfroggy Points 3496

En fait, vous peut combiner QuerySet de la même manière. C'est ainsi :

C.objects.filter(classA__fieldOfA='foo') | C.objects.filter(classB__fieldOfB='foo')

2voto

Vinay Sajip Points 41286

Si vous pouvez être sûr qu'un C a soit un A, soit un B, mais jamais les deux, votre isnull sont redondantes. Que se passe-t-il si vous exécutez la procédure suivante ?

C.objects.filter(Q(classA__fieldOfA = 'foo') | Q(classB__fieldOfB = 'foo'))

Si cela ne fonctionne toujours pas, lancez manage.py shell et après avoir exécuté la requête ci-dessus (en s'assurant que settings.DEBUG es True vérifiez le code SQL généré pour ce qui précède avec

>>> from django.db import connection
>>> connection.queries()

Que voyez-vous ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X