2017-10-20 6 views
1

Je veux demander les premiers éléments x qui dépassent ensemble un montant spécifique et je ne sais pas si cela est en quelque sorte possible. Alors que ce supposant est mon modèle:Requête Django - obtenir les premiers x éléments qui dépassent ensemble une quantité spécifique pour un champ

class Article(models.Model): 
    price = models.DecimalField(default=0.0, max_digits=7, decimal_places=2) 

Maintenant, si je commande le Articles par le price Je veux la première Articles qui, ensemble, dépasser la price de disons 100 dollars. Est-ce que c'est en quelque sorte possible avec annotation, addition, extra() ou autre?

Article.objects.order_by("price") 

par exemple: J'ai 3 articles:

Article1 (price=50 Dollar) 
Article2 (price=60 Dollar) 
Article3 (price=20 Dollar) 

.... Maintenant, je veux que les articles qui dépassent ensemble le prix de 100 dollars ... donc ce serait Article1 ET Article2 . Ensemble, la valeur est de 110 Dollars

Cette réponse dans les déclarations sql premières serait dir il truc mais je ne sais pas comment résoudre avec cette syntaxe django limiting the rows to where the sum a column equals a certain value in MySQL

+0

Comment dites-vous first x elements? Créé en premier? –

+0

Disons que j'ai 3 Articles: Article1 (prix = 50 Dollar) Article2 (prix = 60 Dollar) et Article3 (prix = 20 Dollar) .... Maintenant, je veux les articles qui, ensemble, dépassent le prix de 100 Dollar. ..so ce serait l'article 1 et l'article 2. Ensemble, la valeur est de 110 Dollars –

+0

Je ne peux penser à rien sans utiliser un forloop. –

Répondre

1

Je ne pense pas que vous serez en mesure de cette purement avec une requête de base de données. La question SQL à laquelle vous avez lié a des réponses qui nécessitent une procédure stockée, ou qui sont très coûteuses (O (N^2)).

Vous pouvez obtenir la même chose avec une requête d'itérateur efficace et nécessitant une manipulation très simple en Python. Quelque chose comme ceci:

articles = Article.objects.order_by("price").iterator() 
to_update = [] 
total = 0 
for article in articles: 
    total += article.price 
    if total > 100: 
     break 
    to_update.append(article.pk) 

# Select the affected objects for update 
Article.objects.select_for_update().filter(pk__in=to_update) 

Parce que vous utilisez iterator() vous ne serez récupérez les objets dont vous avez besoin de la base de données.

+0

Qu'est-ce avec ceci: Article.objects.annotate (total_price = Somme (, prix ')). Filter (total_price__lte = 100)? Je pense que je vais essayer cela –

+0

Essayez-le ... Je ne suis pas sûr que cela fonctionnera et si c'est le cas, ce sera O (N^2), plus cher que juste itératif. – solarissmoke

+0

le problème est que je dois faire un select_for_update et c'est juste possible sur les ensembles de requêtes:/ –