2010-05-17 16 views
75

¿Hay alguna manera de establecer una relación de clave externa usando la identificación de entero de un modelo? Esto sería para fines de optimización.Django: ¿Establecer clave foránea usando enteros?

Por ejemplo, supongamos que tengo un modelo empleado:

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

y

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

Quiero la flexibilidad de tener tipos de empleados ilimitadas, pero en la aplicación desplegada probablemente habrá solamente una solo tipo, así que me pregunto si hay una forma de codificar el ID y configurar la relación de esta manera. De esta forma puedo evitar una llamada a db para obtener primero el objeto EmployeeType.

Respuesta

171

Sí:

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

ForeignKey campos almacenar su valor en un atributo con _id al final, al que puede acceder directamente a evitar la visita a la base de datos.

La versión _id de un ForeignKey es un aspecto particularmente útil de Django, que todos deberían conocer y usar de vez en cuando cuando corresponda.

advertencia:

@RuneKaagaard señala que employee.type no es precisa después en las últimas versiones de Django, incluso después de llamar employee.save() (que mantiene su valor anterior). Usarlo, por supuesto, vencería el propósito de la optimización anterior, pero preferiría que una consulta extra accidental fuera incorrecta. Así que tenga cuidado, solo use esto cuando haya terminado de trabajar en su instancia (por ejemplo, employee).

+7

Es esta documentado? –

+0

[modelo '.save()'] (https://github.com/django/django/blob/731f313d604a6cc141f36d8a1ba9a75790c70154/django/db/models/base.py#L708) utiliza el campo 'attname' ([' pre_save () 'devuelve el valor' attname'] (https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L602)). Para ForeignKeys, 'attname' es el nombre con el sufijo' _id'. Además, el atributo 'foobar_id' de una instancia modelo se [actualiza automáticamente] (https://github.com/django/django/blob/master/django/db/models/fields/related.py#L467) cuando configura 'foobar'. Pero, ¿dónde está documentado oficialmente? –

+5

Usar valores de claves foráneas directamente: https://docs.djangoproject.com/en/1.8/topics/db/optimization/#use-foreign-key-values-directly –

28

Una alternativa que utiliza create para crear el objeto y guardarlo en la base de datos en una sola línea:

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