web-dev-qa-db-fra.com

Django filtre order_by () avec distinct ()

Comment puis-je faire un order_by comme ça ....

p = Product.objects.filter(vendornumber='403516006')\
                   .order_by('-created').distinct('vendor__name')

Le problème est que j'ai plusieurs fournisseurs portant le même nom et que je ne veux que le dernier produit du fournisseur.

J'espère que cela a du sens?

J'ai cette erreur DB:

Les expressions SELECT DISTINCT ON doivent correspondre aux expressions ORDER BY initiales LIGNE 1: SELECT DISTINCT ON ("search_vendor". "Name") "search_product" ...

41
pkdkk

Sur la base de votre message d'erreur et cette autre question , il me semble que cela le corrigerait:

p = Product.objects.filter(vendornumber='403516006')\
               .order_by('vendor__name', '-created').distinct('vendor__name')

Autrement dit, il semble que le DISTINCT ON les expressions doivent correspondre à l'extrême gauche ORDER BY expressions). Donc, en créant la colonne que vous utilisez dans distinct comme première colonne dans le order_by, Je pense que ça devrait marcher.

48
janos

Le simple fait de faire correspondre l'argument order_by () le plus à gauche et distinct () ne fonctionnait pas pour moi, produisant la même erreur (bug Django 1.8.7 ou fonctionnalité)?

qs.order_by('project').distinct('project')

mais cela a fonctionné quand j'ai changé pour:

qs.order_by('project_id').distinct('project')

et je n'ai même pas plusieurs arguments order_by.

13
Dmitriy Sintsov

Dans le cas où vous espérez utiliser un champ séparé pour distinct et ordonné par un autre champ, vous pouvez utiliser le code ci-dessous

from Django.db.models import Subquery

Model.objects.filter(
    pk__in=Subquery(
       Model.objects.all().distinct('foo').values('pk')
    )
).order_by('bar')
5
kophygiddie

J'ai eu un problème similaire mais avec des domaines connexes. Avec juste l'ajout du champ associé dans distinct(), je n'ai pas obtenu les bons résultats.

Je voulais trier par room__name en gardant le person (lié à residency) unique. La répétition du champ connexe comme ci-dessous a résolu mon problème:

.order_by('room__name', 'residency__person', ).distinct('room__name', 'residency__person')

Voir également ces articles connexes:

2
SaeX