2012-05-16 14 views
13

C'è un modo per non dover passare in un'istanza di modello per una chiave esterna quando si crea un nuovo modello? Diciamo che ho i seguenti modelli: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' 

Più tardi una richiesta POST viene a vista - So che il l'ID di un record di foo e voglio solo inserire un record nella tabella bar.

se faccio:

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

ottengo un ValueError che dice "Impossibile assegnare "546456487466L": " Bar.foo" solo una "istanza Foo"

Così, ho capito. .. mi vuole una vera istanza del modello Foo. Capisco che posso solo fare un salto su Foo e poi passarlo. Ma sembra che ci debba essere un modo per scavalcare questa funzionalità. alcuni googling e la lettura dei documenti, e raw_id_fields in admin sembra essere l'idea di base. (Vale a dire, consentire un ID raw qui)., Ma non vedere questa opzione nel campo ForeignKey.

Sembra molto inefficiente dover effettuare un round trip nel database per ottenere un oggetto per ottenere l'id (che ho già). Capisco che facendo il viaggio di andata convalida che l'ID esiste nel database. Ma, hey ... ecco perché sto usando un RDBMS e ho le chiavi esterne in primo luogo.

Grazie

+0

Grande, classica domanda SO-ish. – trpt4him

risposta

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

È inoltre possibile ottenere foreign key values directly. Un qualche tipo di ottimizzazione.

+0

Questo ha funzionato ... Ho ancora avuto problemi finché non ho capito qualcosa. aggiungerò qui una piccola nota e modificherò la risposta sopra. Nel mio esempio sopra, in realtà ho finito per semplificare un po '. Nei modelli REAL, "foo" la chiave primaria del tavolo non era "id". E lo straniero non era "foo_id". Ma hai ANCORA bisogno di usare il fieldname + "_ id" per farlo funzionare. –

+1

Non è strano che non sia un doppio segno di sottolineatura, poiché id è un campo di Foo. Si usa un doppio trattino di sottolineatura almeno nei querysets. – radtek

+0

@radtek perché non stai usando il campo id di Foo, stai usando il campo foo_id di Bar. Se usi una sorta di client di database vedrai che 'appname_foo' ha una colonna' id' e 'appname_bar' ha una colonna' foo_id'. Voglio dire altrimenti, come sapresti quale Foo va in ogni Bar? Quindi in questo caso anche in querysets NON dovresti (e NON dovresti) usare una doppia sottolineatura quando si tratta di id, (si evita un join in questo modo). – semicolon

Problemi correlati