Seleccionar los valores distintos de un campo de tabla
-
20-09-2019 - |
Pregunta
Estoy luchando conseguir mi cabeza alrededor del ORM de Django. Lo que quiero hacer es obtener una lista de valores distintos dentro de un campo en mi mesa .... el equivalente de uno de los siguientes:
SELECT DISTINCT myfieldname FROM mytable
(o alternativamente)
SELECT myfieldname FROM mytable GROUP BY myfieldname
Me gustaría al menos hacerlo de la manera Django antes de recurrir a SQL prima. Por ejemplo, con una tabla:
Identificación, calle, ciudad
1, Main Street, Hull
2, otra calle, Hull
3, Bibble Way, Leicester
4, otro camino, Leicester
5, Calle principal, Londidium
Me gustaría llegar:
Hull, Leicester, Londidium.
Solución
Digamos que su modelo es 'Comprar'
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')
Dado que es posible que tenga el conjunto de la clase Meta
atributo ordering
, puede utilizar order_by()
sin parámetros para despejar cualquier ordenación cuando se utiliza distinct()
. Consulte la documentación de bajo order_by
()
Si no desea que cualquier ordenación que se aplicará a una pregunta, ni siquiera el orden predeterminado, llame order_by () sin ningún parámetro.
distinct()
en la nota donde se discute cuestiones con el uso de distinct()
con el pedido.
Para consultar su base de datos, sólo tiene que llamar a:
models.Shop.objects.order_by().values('city').distinct()
Devuelve un dictionnary
o
models.Shop.objects.order_by().values_list('city').distinct()
Éste devuelve un ValuesListQuerySet
que puede convertirse a un list
.
También se pueden añadir a flat=True
values_list
para aplanar los resultados.
Vea también: obtener valores distintos de queryset por campo
Otros consejos
Además de la respuesta siendo muy relevante de jujule , me parece muy importante también tener en cuenta las implicaciones de order_by()
en consultas distinct("field_name")
. Este es, sin embargo, un Postgres única característica!
Si está utilizando Postgres y si se define un nombre de campo que la consulta debe ser distinto para, a continuación, order_by()
necesita comenzar con el mismo nombre de campo (o nombres de campo) en la misma secuencia (puede haber más campos después) .
Nota:
Al especificar nombres de campo, debe proporcionar un order_by () en el QuerySet, y los campos en order_by () debe comenzar con los campos de distinct (), en el mismo orden.
Por ejemplo, SELECT DISTINCT ON (a) le da la primera fila por cada valor de la columna a. Si no se especifica un orden, obtendrá alguna fila arbitraria.
Si desea enviar por correo G- extraer una lista de ciudades que conoces en tiendas, el ejemplo de jujule tendría que adaptarse a esto:
# returns an iterable Queryset of cities.
models.Shop.objects.order_by('city').values_list('city', flat=True).distinct('city')
Por ejemplo:
# 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 []