2015-07-16 3 views
3

J'essaie d'utiliser l'ORM de Django pour générer une requête en utilisant des méthodes extra et filter. Quelque chose comme ceci:Django OU requête utilisant Extra et Filtre

Model.objects.filter(clauseA).extra(clauseB).all() 

Cela génère une requête, mais la question est que tout dans la clause de filtre est tout AND avec la clause supplémentaire, de sorte que le sql ressemble:

SELECT * FROM model WHERE clauseA AND clauseB. 

ma question est, est-il possible de changer l'opérateur de combinaison par défaut pour une requête dans Django telle que la requête générée sera:

SELECT * FROM model WHERE clauseA OR clauseB. 
+2

Êtes-vous simplement à la recherche de la [ou de la requête?] (Http://stackoverflow.com/questions/739776/django-filters-ou) (duplication possible) – Sayse

+0

Non, cela ne fonctionne que pour les arguments de la méthode de filtrage. J'ai besoin de changer le combinateur par défaut de telle sorte que ce qui est retourné par la méthode 'extra()' soit OR'd à ce qui est retourné par la méthode 'filter()' (au lieu de AND'd comme c'est actuellement). Ce que j'ai dans la méthode supplémentaire est SQL natif qui ne peut pas être représenté dans l'ORM de Django et ne peut pas être enveloppé avec 'Q' – jcern

+0

Est' Model.objects.filter (Q (clauseA) | Q (clauseB)).() 'n'est pas une solution valide? Je ne vois pas pourquoi vous avez besoin de l'appel séparé (à partir de mes propres tests, ce filtre montré ici produira votre sortie sql souhaitée). Je suis sûr qu'il pourrait être possible de changer le combinateur par défaut mais je ne le conseillerais pas – Sayse

Répondre

3

Essayez Q object

Model.objects.filter(Q(clauseA) | ~Q(clauseB)) 

EDIT

essayer cette

Model.objects.filter(clauseA) | Model.objects.extra(clauseB) 
+1

Merci, le montage était exactement ce que je cherchais. Je n'ai pas réalisé que vous pouviez chaîner les méthodes 'extra' et' filter' avec '&' et '|'. – jcern

0

Il pourrait être plus facile si vous venez de vous débarrasser de la clause de filtre, et inclure ce filtre directement dans votre supplémentaire avec séparées par OR Postgres fonction spécifique. Je pense que c'est déjà une limitation de l'ORM Django.

Cependant, vous pouvez essayer de créer votre propre Func expression. Une fois que vous en avez créé un pour votre fonction spécifique Postgres, vous pouvez utiliser une combinaison d'objets Func(), F() et Q() pour vous débarrasser de cette fonction .extra() désagréable et les chaîner correctement.