supported select_related queryset not fields example equal create django django-models distinct django-queryset django-orm

select_related - group by django



Seleccione DISTINCT columnas individuales en django? (4)

El usuario realiza un pedido con ese campo, y luego lo hace distinto.

ProductOrder.objects.order_by(''category'').values_list(''category'', flat=True).distinct()

Tengo curiosidad por saber si hay alguna forma de hacer una consulta en Django que no sea un " SELECT * FROM... " debajo. Estoy tratando de hacer un " SELECT DISTINCT columnName FROM ... " en su lugar.

Específicamente, tengo un modelo que se ve así:

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

donde el Rank es un rango dentro de una Category . Me gustaría poder iterar sobre todas las categorías realizando alguna operación en cada rango dentro de esa categoría.

Me gustaría obtener primero una lista de todas las categorías en el sistema y luego consultar todos los productos en esa categoría y repetir hasta que se procese cada categoría.

Prefiero evitar el SQL en bruto, pero si tengo que ir allí, estaría bien. Aunque nunca antes he codificado SQL sin formato en Django / Python.


En realidad, es bastante simple si está usando PostgreSQL , solo use distinct(columns) .

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

Tenga en cuenta que esta característica se ha incluido en Django desde 1.4


Las otras respuestas están bien, pero esto es un poco más claro, ya que solo da los valores que obtendría de una consulta DISTINCT, sin ninguna falla de Django.

>>> set(ProductOrder.objects.values_list(''category'', flat=True)) {u''category1'', u''category2'', u''category3'', u''category4''}

o

>>> list(set(ProductOrder.objects.values_list(''category'', flat=True))) [u''category1'', u''category2'', u''category3'', u''category4'']

Y funciona sin PostgreSQL.

Esto es menos eficiente que usar un .distinct (), suponiendo que DISTINCT en su base de datos es más rápido que un set Python, pero es excelente para rodar por el shell.


Una forma de obtener la lista de nombres de columna distintos de la base de datos es usar distinct() junto con values() .

En su caso, puede hacer lo siguiente para obtener los nombres de distintas categorías:

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"

Hay un par de cosas para recordar aquí. En primer lugar, esto devolverá un ValuesQuerySet que se comporta de forma diferente a un QuerySet . Cuando acceda, digamos que el primer elemento de q (arriba) obtendrá un diccionario , NO una instancia de ProductOrder .

En segundo lugar, sería una buena idea leer la distinct() en los documentos sobre el uso de distinct() . El ejemplo anterior funcionará, pero no todas las combinaciones de distinct() y values() .

PD : es una buena idea usar minúsculas para los campos en un modelo. En su caso, esto significaría reescribir su modelo como se muestra a continuación:

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