2017-05-07 3 views
0

Je ces modèles:Django/Postgres: Faites votre choix parmi DISTINCT ON ensembles

class Product(Model): 
    ... 

class Scanning(Model): 
    product = ForeignKey(..) 
    datetime = DateTimeField(...) 
    ... 

Je suis en train d'obtenir un balayage pour chaque produit où le balayage est un dernier un de product.scanning.all() ensemble.

s1 = (product1,01.01.1000) 
s2 = (product2,01.01.1200) 
s3 = (product1,01.01.1900) 
s4 = (product2,01.01.1988) 
s5 = (product3,01.01.2015) 
s6 = (product3,01.01.1970) 

retournerait <s4,s3,s5>

Scanning.objects.filter(product__user=u,product__active=True).distinct('product_id').order_by('datetime') 

Soulève exception:

ProgrammingError: SELECT DISTINCT ON expressions must match initial ORDER BY expressions LINE 1: SELECT DISTINCT ON ("productapp_scanning"."product_id") "pro... ^

Comment faire fonctionner?

Répondre

1

Postgres, vous ne pouvez pas faire distinct sur un terrain, à moins que c'est aussi ce que vous trier par:

Scanning.objects.filter(product__user=u,product__active=True).distinct('product_id').order_by('product_id', 'datetime') 

Si ce n'est pas assez bon, une solution consiste à faire une double requête comme ceci:

q1 = Scanning.objects.filter(product__user=u,product__active=True).values('product_id').distinct().annotate(x=Max('id')) 

q2 = Scanning.objects.filter(id__in=[i["x"] for i in q1])