136 votes

Sélectionnez DISTINCT des colonnes individuelles dans Django?

Je suis curieux de savoir si il y a moyen de faire une requête dans Django qui n'est pas un "SELECT * from..." en dessous. Je suis en train de faire un "SELECT DISTINCT columnName DE ..." à la place.

Plus précisément, j'ai un modèle qui ressemble à:

class ProductOrder(models.Model):
    Product  = models.CharField(max_length=20, promary_key=True)
    Category = models.CharField(max_length=30)
    Rank = models.IntegerField()

d'où le Classement est un classement dans une Catégorie. Je voudrais être en mesure de parcourir toutes les Catégories de faire une opération sur chaque rang dans cette catégorie.

Je voudrais tout d'abord obtenir une liste de toutes les catégories dans le système et une requête pour tous les produits de la catégorie et de la répétition jusqu'à ce que chaque catégorie est traitée.

Je préfère éviter de SQL brut, mais si je dois y aller, ce serait bien. Bien que je n'ai jamais codé SQL brut dans Django/Python avant.

245voto

Manoj Govindan Points 24030

Une manière d'obtenir la liste des différents noms de colonnes de la base de données est d'utiliser distinct() en conjonction avec d' values().

Dans votre cas, vous pouvez effectuer les opérations suivantes pour obtenir les noms des catégories distinctes:

q = ProductOrder.objects.values('Category').distinct()
print q.query # See for yourself.

# The query would look something like
# SELECT DISTINCT "app_productorder"."category" FROM "app_productorder"

Il ya un couple de choses à retenir ici. Tout d'abord, cela retournera ValuesQuerySet qui se comporte différemment à partir d'un QuerySet. Lorsque vous accédez à dire, le premier élément de q (ci-dessus), vous obtiendrez un dictionnaire, PAS une instance d' ProductOrder.

Deuxièmement, il serait une bonne idée de lire la note d'avertissement dans les docs sur l'utilisation d' distinct(). L'exemple ci-dessus fonctionne, mais toutes les combinaisons de distinct() et values() peut pas.

PS: c'est une bonne idée d'utiliser les minuscules des noms de champs dans un modèle. Dans votre cas, cela signifierait la réécriture de votre modèle comme indiqué ci-dessous:

class ProductOrder(models.Model):
    product  = models.CharField(max_length=20, primary_key=True)
    category = models.CharField(max_length=30)
    rank = models.IntegerField()

99voto

Wolph Points 28062

C'est assez simple en fait si vous utilisez PostgreSQL , utilisez simplement distinct(columns) .

 Productorder.objects.all().distinct('category')
 

Notez que cette fonctionnalité est incluse dans Django depuis la 1.4

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X