J'essaie d'utiliser l'API de QuerySet de Django pour imiter la requête suivante:
if(use_date_due): sum_qs = sum_qs.extra(select={'chosen_date': 'CASE WHEN date_due IS NULL THEN date ELSE date_due END'}) else: sum_qs = sum_qs.extra(select={'chosen_date':'date'}) sum_qs = sum_qs.extra(select={'year': 'EXTRACT(year FROM chosen_date)', 'month': 'EXTRACT(month FROM chosen_date)', 'is_paid':'date_paid IS NOT NULL'})
5 Réponses :
Bien voici quelques soluarrages
ou p> Vous pouvez également chaîner autant de CTE que vous le souhaitez: p> donc dans django vous peut utiliser Query brut comme: p> et vous aurez des objets de facturation avec quelques propriétés supplémentaires. p>
Est-ce que cela fonctionnerait?:
from django.db import connection, transaction cursor = connection.cursor() sql = """ SELECT %s AS year, %s AS month, date_paid IS NOT NULL as is_paid FROM ( SELECT (CASE WHEN date_due IS NULL THEN date_due ELSE date END) AS chosen_date, * FROM invoice_invoice ) as t1; """ % (connection.ops.date_extract_sql('year', 'chosen_date'), connection.ops.date_extract_sql('month', 'chosen_date')) # Data retrieval operation - no commit required cursor.execute(sql) rows = cursor.fetchall()
Vous pouvez ajouter une propriété à votre définition de modèle, puis faire:
model_instance.chosen_date.year
En fait, la raison pour laquelle je le fais est parce que, plus tard, je fais une somme d'agrégation basée sur l'année et le mois. Afin de faire cela, je dois appeler valeurs code> avec les valeurs que je veux grouper par ... et je ne peux pas utiliser les recherches sur le terrain comme
__ année code> dans
Valeurs code>.
Une autre chose est que ce que j'utilise pour chrosen_date code> dépend du contexte: parfois j'utilise le
dus_date code> avec la date
Date code> Fallback, parfois juste
Date code>.
Utilisez simplement le SQL brut. La méthode RAW () Manager peut être utilisée pour effectuer des requêtes SQL brutes qui renvoient des instances de modèle. p>
https: //docs.djangoproject .COM / EN / 1.5 / TOWS / DB / SQL / # Effectuer-RAW-SQL-QUERIES P>
une tentative d'expliquer pourquoi: strong> p> Par exemple: p> et aucun de ceux-ci n'est valide SQL. En général, si vous souhaitez utiliser un alias de colonne calculé plusieurs fois dans la sélection ou les clauses de la requête, vous devez réellement le calculer à chaque fois. C'est pourquoi la réponse de Roman Pekar résout votre problème spécifique - au lieu d'essayer de calculer vous mentionne l'annotation / agrégation dans votre question. Vous pouvez utiliser de sorte qu'un exemple: p> produit quelque chose comme: p> utilisant "ayant max alias_col> 0 "ne fonctionnerait pas. P> J'espère que c'est utile. S'il y a quelque chose que j'ai expliqué mal laissé-moi savoir et je verrai si je peux l'améliorer. P> p> extra (SELECT = ...) code>
Ensuite, vous ne pouvez pas utiliser la colonne aliasée dans un appel ultérieur à
filtre () code>.
De plus, comme vous l'avez découvert, vous ne pouvez pas utiliser la colonne aliasée dans les appels ultérieurs vers
extra (SELECT = ...) code> ou
extra (where = ...) code>.
filtrer_qs code> va essayer de produire une requête comme: p>
extra_qs code> essaie quelque chose comme: p>
chrosen_date code> une fois, puis utilisez-le plus tard, il l'a calcule à chaque fois qu'il est nécessaire. P> <
filtre () code> sur les alias créés par
annotate () code> (Donc, je voudrais voir les erreurs similaires dont vous parlez, il a été assez robuste dans mon expérience). C'est parce que lorsque vous essayez de filtrer sur un alias créé par Annotate, l'ORM reconnaît ce que vous faites et remplace l'alias avec le calcul qui l'a créée. p>
Je garderais cela simple et utiliser une requête crue. C'est ce qu'ils sont là pour.