2011-10-26 16 views
8

ERRORM de Django SELECT con unirse

modelos de Django:

class Key(models.Model): 
    id  = models.AutoField(primary_key=True, blank=True) 
    name = models.CharField(max_length=50) 


class Record(models.Model): 
    id   = models.AutoField(primary_key=True, blank=True) 
    project_id = models.IntegerField() 
    name  = models.CharField(max_length=50) 


class Value(models.Model): 
    id  = models.AutoField(primary_key=True, blank=True) 
    record = models.ForeignKey(Record) 
    key  = models.ForeignKey(Key) 
    value  = models.CharField(max_length=255) 

necesito para seleccionar de DB estos datos:

NAME (from record) 
and fields related with this record 
[NAME (from key), VALUE (from value)] 
[NAME (from key), VALUE (from value)] 
[...] 

¿Puedo usar ORM de Django para hacer esta selección? (por ejemplo, en la selección de SQL se ve así)

SELECT 
    `keeper_record`.`id` AS `record_id`, 
    `keeper_record`.`name` AS `name`, 
    `keeper_record`.`desc` AS `desc`, 
    `keeper_key`.`name` AS `key_name`, 
    `keeper_key`.`desc` AS `key_desc`, 
    `keeper_value`.`value` AS `value_value` 
FROM `keeper_record` 
JOIN `keeper_value` ON `keeper_record`.`id` = `keeper_value`.`record_id` 
JOIN `keeper_key` ON `keeper_key`.`id` = `keeper_value`.`key_id` 
WHERE record_id = id 

Respuesta

7

Lo siguiente selecciona los valores relacionados con la identificación de registro particular. Luego puede seguir las claves externas para obtener el registro y la clave relacionados. El uso de select_related minimiza las búsquedas en la base de datos.

# Select all values related to a record in your view 
record = Record.objects.get(pk=record_id) 
values = Value.objects.filter(record=record).select_related() 

# In your template 
{% for value in values %} 
{{ value.record.name }} - {{ value.key.name }} - {{ value.value }} 
{% endfor %} 

Selección de más de un registro

En su SQL, que tenían WHERE record_id = 1, por lo que mostró cómo conseguir todos los valores de un registro en particular. También puede seleccionar los valores para más de un registro en una consulta.

# filter all records which belong to the project with `project_id=1` 
records = Record.objects.filter(project_id=1) 
# select all values that belong to these records 
values = Value.objects.filter(record__in=records).select_related().order_by('record') 
+0

He comprendido correctamente, que para cada registro necesito una consulta adicional para seleccionar valores, y si quiero seleccionar todos (o algunos) registros, ¿necesito seleccionar valores en un ciclo? – Deadly

+2

He actualizado la respuesta para seleccionar más de un registro. Espero eso ayude. – Alasdair

+0

Sí, realmente me ayudó a entender django ORM, gracias. – Deadly

2

Debe ser relativamente sencillo, ya que ya tiene las claves externas atadas.

Record.objects.select_related().filter(id = variable_that_stores_id) 

Puede combinar eso con only para limitar los campos que desee para traer de vuelta.

+0

'select_related' no funcionará aquí, porque no sigue la clave externa 'hacia atrás'. – Alasdair

+0

Ya veo. Parece que la pregunta ha cambiado un poco desde mi publicación, pero independientemente de que sea incorrecta o incompleta. – Jordan