Django: установить внешний ключ с использованием целого числа?


104

Есть ли способ установить отношения внешнего ключа с использованием целочисленного идентификатора модели? Это было бы в целях оптимизации.

Например, предположим, что у меня есть модель сотрудников:

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

и

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

Мне нужна гибкость наличия неограниченного количества типов сотрудников, но в развернутом приложении, вероятно, будет только один тип, поэтому мне интересно, есть ли способ жестко закодировать идентификатор и установить отношения таким образом. Таким образом я могу избежать вызова db для получения сначала объекта EmployeeType.

Ответы:


206

Ага:

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

ForeignKey поля хранят свое значение в атрибуте с _id в конце, к которому вы можете получить доступ напрямую, чтобы избежать посещения базы данных.

_idВерсия ForeignKeyявляется особенно полезным аспектом Django, один , что каждый должен знать и использовать время от времени , когда это необходимо.

предостережение:

@RuneKaagaard указывает, что employee.typeвпоследствии в последних версиях Django это неточно, даже после вызова employee.save()(оно сохраняет свое старое значение). Его использование, конечно, лишило бы цели вышеуказанной оптимизации, но я бы предпочел, чтобы случайный дополнительный запрос был неверным. Так что будьте осторожны, используйте это только тогда, когда вы закончите работу над своим экземпляром (например employee).


10
Это задокументировано?
Скотт Стаффорд


1
Сегодня я тестировал это на Django 1.7, и там это не очень хорошая идея. Хотя он работает и typeполе записывается в базу данных, если вы typeвпоследствии получите доступ к свойству, оно не отражает изменения. В коде сказано, что это не удастся assert(employe.type.id == 4).
Руне Каагаард

3
@AmichaiSchreiber Я считаю, что в следующем выпуске Django эта проблема будет исправлена: code.djangoproject.com/ticket/27710
Will Hardy

2
Для тех, кто придет сюда в будущем, эта проблема исправлена ​​в Django 2.1 .
Humcat

45

Альтернатива, использующая create для создания объекта и сохранения его в базе данных в одной строке:

employee = Employee.objects.create(first_name='first', last_name='last', type_id=4)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.