comment trier par une valeur calculée dans django
-
06-09-2019 - |
Question
Hé, je veux trier les objets en fonction d'une valeur calculée dans django ... Comment puis-je faire?
Voici un exemple modèle de profil d'utilisateur basé sur pile débordement qui explique ma situation:
class Profile(models.Model):
user = models.ForeignKey(User)
def get_reputation():
...
return reputation
reputation = property(get_reputation)
Alors, dis que je veux trier les utilisateurs par la réputation. Comment je fais ça? Je sais que vous ne pouvez pas faire ceci:
Profile.objects.order_by("-reputation")
Merci pour votre aide tout le monde:)
La solution
Si vous avez besoin de faire le tri dans la base de données (parce que vous avez beaucoup de dossiers et doivent par exemple les paginera), la seule véritable option est de transformer la réputation dans un champ dénormalisé (par exemple, mis à jour dans une méthode de save()
surchargée sur le modèle).
Autres conseils
Étant donné que votre code de calcul existe uniquement dans Python, vous devez effectuer le tri en Python ainsi:
sorted (Profile.objects.all (), key = lambda p: p.reputation)
de Django-1.8, il est possible de trier un QuerySet en utilisant expressions de requête tant que la valeur calculée peut être rendue dans SQL. Vous pouvez également utiliser annotations
au modèle comme order_by
terme.
from django.db.models import F
Profile.objects.annotate(reputation=(F('<field>') + ...)).order_by("-reputation")
Opérations de base comme +
, -
, *
, /
et **
peuvent être utilisés avec F()
. En outre, il existe plusieurs autres fonctions telles que Count
, Avg
, Max
, ...
Liens:
- agrégation -
order_by
- faire les requêtes - filtres peuvent référencer des champs sur un modèle
- expressions de requête - Construit dans les expressions
Voir aussi ce SO Q & A: Commander un QuerySet par la valeur du champ global