J'ai une liste d'objets comment puis-je exécuter une requête pour donner la valeur maximale d'un champ:
J'utilise ce code:
def get_best_argument(self):
try:
arg = self.argument_set.order_by('-rating')[0].details
except IndexError:
return 'no posts'
return arg
note est un entier
Voir ceci . Votre code ressemblerait à ceci:
from Django.db.models import Max
# Generates a "SELECT MAX..." query
Argument.objects.aggregate(Max('rating')) # {'rating__max': 5}
Vous pouvez également l'utiliser sur des ensembles de requêtes existants:
from Django.db.models import Max
args = Argument.objects.filter(name='foo') # or whatever arbitrary queryset
args.aggregate(Max('rating')) # {'rating__max': 5}
Si vous avez besoin de l'instance de modèle qui contient cette valeur maximale, le code que vous avez publié est probablement le meilleur moyen de le faire:
arg = args.order_by('-rating')[0]
Notez que cela générera une erreur si l'ensemble de requêtes est vide, c'est-à-dire si aucun argument ne correspond à la requête (car la partie [0]
Lèvera un IndexError
). Si vous voulez éviter ce comportement et retourner simplement à la place None
dans ce cas, utilisez .first()
:
arg = args.order_by('-rating').first() # may return None
Django possède également la fonction ' latest (field_name = None) ' qui trouve la dernière entrée (valeur max.). Cela fonctionne non seulement avec les champs de date mais aussi avec les chaînes et les entiers.
Vous pouvez donner le nom du champ lors de l'appel de cette fonction:
max_rated_entry = YourModel.objects.latest('rating')
return max_rated_entry.details
Ou vous pouvez déjà donner ce nom de champ dans les métadonnées de vos modèles:
from Django.db import models
class YourModel(models.Model):
#your class definition
class Meta:
get_latest_by = 'rating'
Vous pouvez maintenant appeler 'latest ()' sans aucun paramètre:
max_rated_entry = YourModel.objects.latest()
return max_rated_entry.details
J'ai testé cela pour mon projet, il trouve le max/min dans O(n) time:
from Django.db.models import Max
#Find the maximum value of the rating, and then get the record with that rating. Notice the double underscores in rating__max
max_rating = App.objects.all().aggregate(Max('rating'))['rating__max']
return App.objects.get(rating = max_rating)
Cela vous garantit d'obtenir l'un des éléments maximaux efficacement, plutôt que de trier la table entière et d'obtenir le haut (autour de O (nlogn)).