176 votes

Sélectionner des valeurs distinctes dans un champ de table

J'ai du mal à me faire une idée de l'ORM de Django. Ce que je veux faire, c'est obtenir une liste de valeurs distinctes dans un champ de ma table .... l'équivalent de l'un des éléments suivants :

SELECT DISTINCT myfieldname FROM mytable

(ou alternativement)

SELECT myfieldname FROM mytable GROUP BY myfieldname

J'aimerais au moins pouvoir le faire à la manière de Django avant d'avoir recours au sql brut. Par exemple, avec une table :

id, rue, ville

1, rue principale, Hull

2, Autre rue, Hull

3, Bibble Way, Leicester

4, Another Way, Leicester

5, High Street, Londidium

J'aimerais obtenir :

Hull, Leicester, Londidium.

317voto

jujule Points 4353

Disons que votre modèle est "Shop

class Shop(models.Model):
    street = models.CharField(max_length=150)
    city = models.CharField(max_length=150)

    # some of your models may have explicit ordering
    class Meta:
        ordering = ('city',)

Puisque vous pouvez avoir le Meta classe ordering (qui est un tuple ou une liste), vous pouvez utiliser l'attribut order_by() sans paramètres pour effacer toute commande lors de l'utilisation de distinct() . Voir la documentation sous order_by ()

Si vous ne souhaitez pas qu'un ordre quelconque soit appliqué à une requête, pas même l'ordre par défaut, appelez order_by() sans paramètres.

et distinct() dans la note où il est question des problèmes liés à l'utilisation des distinct() avec commande.

Pour interroger votre base de données, il vous suffit d'appeler :

models.Shop.objects.order_by().values('city').distinct()

Il renvoie un dictionnaire

ou

models.Shop.objects.order_by().values_list('city').distinct()

Celui-ci renvoie un ValuesListQuerySet que vous pouvez transformer en list . Vous pouvez également ajouter flat=True a values_list pour aplanir les résultats.

Voir aussi Obtenir des valeurs distinctes de Queryset par champ

30voto

ingofreyer Points 589

En plus de la toujours très pertinente réponse de jujule Je pense qu'il est très important d'être conscient des implications de l'utilisation de la technologie de l'information et de la communication. order_by() sur distinct("field_name") questions. Il s'agit toutefois d'une fonctionnalité propre à Postgres !

Si vous utilisez Postgres et si vous définissez un nom de champ pour lequel la requête doit être distincte, alors order_by() doit commencer par le même nom de champ (ou les mêmes noms de champ) dans la même séquence (il peut y avoir d'autres champs par la suite).

Nota

Lorsque vous spécifiez des noms de champs, vous devez fournir une fonction order_by() dans la directive QuerySet, et les champs de order_by() doivent commencer par les champs de distinct(), dans le même ordre.

Par exemple, SELECT DISTINCT ON (a) vous donne la première ligne pour chaque valeur de la colonne a. valeur de la colonne a. Si vous ne spécifiez pas d'ordre, vous obtiendrez une ligne arbitraire. ligne arbitraire.

Si vous souhaitez par exemple extraire une liste de villes dans lesquelles vous connaissez des magasins, l'exemple de jujule devra être adapté :

# returns an iterable Queryset of cities.
models.Shop.objects.order_by('city').values_list('city', flat=True).distinct('city')

3voto

Roger Points 158

A titre d'exemple :

# select distinct code from Platform where id in ( select platform__id from Build where product=p)
pl_ids = Build.objects.values('platform__id').filter(product=p)
platforms = Platform.objects.values_list('code', flat=True).filter(id__in=pl_ids).distinct('code')
platforms = list(platforms) if platforms else []

2voto

Mahdi mehrabi Points 157

Si vous ne utiliser PostgreSQL et que vous voulez seulement obtenir un champ distinct avec un seul champ spécifique, vous pouvez utiliser

MyModel.objects.values('name').annotate(Count('id')).order_by()

Cette requête nous renvoie les lignes dont le champ 'name' est unique avec le nombre de lignes qui ont le même nom.

<QuerySet [{'name': 'a', 'id__count': 2}, {'name': 'b', 'id__count': 2}, {'name': 'c', 'id__count': 3}>

Je sais que les données renvoyées ne sont pas complètes et qu'elles ne sont pas toujours satisfaisantes, mais elles sont parfois utiles.

référence du document

2voto

Jitendra Meena Points 1

L'instruction SELECT DISTINCT est utilisée pour renvoyer uniquement des valeurs distinctes (différentes). Dans une table, une colonne contient souvent de nombreuses valeurs en double ; l'utilisation de l'instruction distinct() nous pouvons obtenir des données uniques.

event = Event.objects.values('item_event_type').distinct()
serializer= ItemEventTypeSerializer(event,many=True)
return Response(serializer.data)

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