2012-05-16 10 views
13

¿Hay alguna manera de no tener que pasar una instancia de modelo para una clave externa cuando se crea un nuevo modelo? Digamos que tengo los siguientes modelos:Django ForeignKey Instance vs Raw ID

class Foo(models.Model): 
    description = models.CharField(max_length=100) 

    class Meta: 
     db_table = u'foo' 

class Bar(models.Model): 
    info = models.CharField(max_length=100) 
    foo = models.ForeignKey('Foo') 

    class Meta: 
     db_table = u'bar' 

Cuanto más tarde una solicitud posterior viene a una vista - Sé que el el id de un registro foo y sólo quiero insertar un registro en la tabla de la barra.

si lo hago:

new_bar = Bar(info="something important", foo=foo_id) 
new_bar.save() 

me sale un dicho "No se puede asignar "546456487466L ValueError": " Bar.foo" apenas sea una "instancia de Foo"

Por lo tanto, lo entiendo. .. quiere que tenga una instancia real del modelo Foo. Entiendo que puedo acceder a Foo y luego pasarlo. Pero, parece que debe haber una manera de anular esta funcionalidad. Lo he hecho algunos googleando y leyendo los documentos, y raw_id_fields en admin parece ser la idea básica (es decir, permitir una identificación en bruto aquí). Pero, no vea esta opción en el campo ForeignKey.

Parece muy ineficiente tener que hacer un viaje de ida y vuelta a la base de datos para obtener un objeto para obtener la identificación (que ya tengo). Entiendo que hacer el viaje de ida y vuelta valida que la identificación exista en la base de datos. Pero, oye ... es por eso que estoy usando un RDBMS y tengo claves foráneas en primer lugar.

Gracias

+0

Excelente, clásica pregunta SO-ish. – trpt4him

Respuesta

20
new_bar = Bar(info="something important", foo_id=12345) 
new_bar.save() 

También puede obtener foreign key values directly. Algún tipo de optimización

+0

Esto funcionó ... Todavía tenía problemas hasta que resolví algo. voy a agregar 1 pequeña nota aquí y edito la respuesta anterior. En mi ejemplo anterior, en realidad me simplifiqué un poco. En los modelos REALES, "foo" la clave principal de la tabla no era "id". Y el extranjero no era "foo_id". Pero, TODAVÍA necesita usar el nombre de campo + "_ id" para que funcione. –

+1

¿No es extraño que no sea un doble guión bajo, ya que id es un campo de Foo? Utiliza un guion bajo doble en querysets al menos. – radtek

+0

@radtek eso es porque no estás usando el campo de identificación de Foo, estás usando el campo foo_id de Bar. Si utiliza algún tipo de cliente de base de datos, verá que 'appname_foo' tiene una columna' id' y 'appname_bar' tiene una columna' foo_id'. Quiero decir, ¿cómo sabrías qué Foo va a cada Bar? Por lo tanto, en este caso, incluso en los conjuntos de consulta, NO (y NO debería) usar un guion bajo doble cuando se trata de identificadores (se evita una unión de esa manera). – semicolon