2010-05-17 13 views
75

C'è un modo per impostare la relazione di chiave esterna utilizzando l'ID intero di un modello? Questo sarebbe per scopi di ottimizzazione.Django: imposta la chiave esterna con l'intero?

Per esempio, supponiamo di avere un modello di organigramma:

class Employee(models.Model): 
    first_name = models.CharField(max_length=100) 
    last_name = models.CharField(max_length=100) 
    type = models.ForeignKey('EmployeeType') 

e

EmployeeType(models.Model): 
    type = models.CharField(max_length=100) 

Voglio la flessibilità di avere tipi dipendenti illimitate, ma l'applicazione distribuita ci sarà probabilmente solo singolo tipo quindi mi chiedo se c'è un modo per hardcode l'id e impostare la relazione in questo modo. In questo modo posso evitare una chiamata db per ottenere prima l'oggetto EmployeeType.

risposta

171

Yep:

employee = Employee(first_name="Name", last_name="Name") 
employee.type_id = 4 
employee.save() 

ForeignKey campi memorizzare il loro valore in un attributo con _id alla fine, che è possibile accedere direttamente a evitare di visitare il database.

La versione _id di un ForeignKey è un aspetto particolarmente utile di Django, uno che tutti dovrebbero conoscere e utilizzare di volta in volta quando appropriato.

avvertimento:

@RuneKaagaard sottolinea che employee.type non è esatto dopo, nelle versioni più recenti Django, anche dopo aver chiamato employee.save() (che detiene il suo vecchio valore). Ovviamente, l'utilizzo di questo metodo vanificherebbe lo scopo dell'ottimizzazione di cui sopra, ma preferirei una query aggiuntiva accidentale a non essere corretta. Quindi, fai attenzione, usalo solo quando hai finito di lavorare sulla tua istanza (es. employee).

+7

È questo documentato? –

+0

[model '.save()'] (https://github.com/django/django/blob/731f313d604a6cc141f36d8a1ba9a75790c70154/django/db/models/base.py#L708) usa il campo 'nomname' ([' pre_save () 'restituisce il valore' attname'] (https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L602)). Per ForeignKeys, 'attname' è il nome con suffisso' _id'. Inoltre, l'attributo 'foobar_id' di un'istanza di modello è [aggiornato automaticamente] (https://github.com/django/django/blob/master/django/db/models/fields/related.py#L467) quando si imposta 'foobar'. Ma dove è documentato ufficialmente? –

+5

Utilizzo di valori di chiave esterna direttamente: https://docs.djangoproject.com/en/1.8/topics/db/optimization/#use-foreign-key-values-directly –

28

Un'alternativa che utilizza create per creare l'oggetto e salvarlo al database in una sola riga:

employee = Employee.objects.create(first_name='first', last_name='last', type_id=4) 
Problemi correlati