2012-03-15 13 views
34

lo que quería saber, ¿hay algo equivalente a:Django: Equivalente de "seleccionar [nombre de la columna] de [nombre de tabla]"

select columnname from tablename 

Como Django tutorial dice:

Entry.objects.filter(condition) 

Obtiene toda la objetos con la condición dada. Es como:

select * from Entry where condition 

Pero quiero hacer una lista de una sola columna [que en mi caso es una clave externa]. Encontrado que:

Entry.objects.values_list('column_name', flat=True).filter(condition) 

hace lo mismo. Pero en mi caso, la columna es una clave externa, y esta consulta pierde la propiedad de una clave externa. Solo almacena los valores. No puedo hacer las llamadas de búsqueda.

+1

Empecé a escribir una respuesta, y ahora no estoy seguro. ¿Desea que django devuelva un objeto desde la clave externa, o desea la clave en sí? –

Respuesta

51

Por supuesto, values y value_list recuperarán los valores sin procesar de la base de datos. Django no puede trabajar su "magia" en un modelo, lo que significa que no puede atravesar las relaciones porque está atascado con el ID al que apunta la clave externa, en lugar del campo ForeignKey.

Si necesita filtros esos valores, puede hacer lo siguiente (column_name suponiendo que es una ForeignKey señalando MyModel):

ids = Entry.objects.values_list('column_name', flat=True).filter(...) 
my_models = MyModel.objects.filter(pk__in=set(ids)) 

Aquí hay una documentación para values_list()

+1

esto puede funcionar, pero si fuera yo Yo no estoy feliz de tener que hacer dos llamadas a la base de datos. @Gareth Rees tiene un mejor enfoque: voltea la consulta y escríbela desde la perspectiva del objeto que deseas y aprovecha el related_name – ThatAintWorking

5

delimitar una consulta establecido en una columna (s) específico que utilice .values ​​(columname)

También debe probablemente un signo profundo hasta el final, por lo que la consulta va a terminar siendo:

Entry.objects.filter(myfilter).values(columname).distinct() 

Ver: https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values

para más información

Dependiendo de su respuesta en el comentario, voy a volver y editar.

Editar:

No estoy seguro de si el enfoque es más adecuado sin embargo. Puede obtener todos los objetos en una lista de Python por conseguir un queryset normal a través del filtro y luego hacer:

myobjectlist = map(lambda x: x.mycolumnname, myqueryset) 

El único problema con este enfoque es si su queryset es grande es su uso de la memoria va a ser igual de grande .

De todos modos, todavía no estoy seguro de algunos de los detalles del problema.

+2

values ​​() está dando resultados similares a values_list(). Obtengo los valores de la columna 'usuario' como 1L, 2L ... pero la relación de la clave externa se pierde. No puedo acceder a la clase 'usuario'. – Anuj

+0

Necesita 'order_by' para que' distinct' haga su trabajo. –

+0

una solución similar, igualmente no elegante para obtener los elementos en lugar de ID's es: [instance.member por ejemplo en Entry.filter (condición) .distinct ('miembro')] – Nimo

9

tiene un modelo A con una clave foránea a otro modelo B, y desea seleccionar B s a los que hace referencia algún A. ¿Está bien?Si es así, la consulta que desea es simplemente:

B.objects.filter(a__isnull = False) 

Si usted tiene condiciones de la correspondiente A, la consulta puede ser:

B.objects.filter(a__field1 = value1, a__field2 = value2, ...) 

Ver Django's backwards relation documentation para una explicación de por qué esto funciona, y ForeignKey.related_name option si desea cambiar el nombre de la relación hacia atrás.

+0

. Creo que este es el mejor enfoque, pero probablemente deberías mencionar el nombre relacionado – ThatAintWorking

+2

@Ron: Agregué enlaces a la documentación. –

Cuestiones relacionadas