Установка значения по умолчанию для атрибута Foreign Key
Каков наилучший способ установить значение по умолчанию для поля внешнего ключа в модели? Предположим, у меня есть две модели: Студент и Экзамен со студентом, имеющим exam_taken как иностранный ключ. Как бы я идеально установил для него значение по умолчанию? Здесь журнал моих усилий
class Student(models.Model):
....
.....
exam_taken = models.ForeignKey("Exam", default=1)
Работает, но есть догадка, что лучше.
def get_exam():
return Exam.objects.get(id=1)
class Student(models.Model):
....
.....
exam_taken = models.ForeignKey("Exam", default=get_exam)
Из здесь, но с ошибками с таблицами не возникает ошибка во время синхронизации.
Любая помощь будет оценена по достоинству.
Ответы
Ответ 1
В обоих примерах вы жестко кодируете идентификатор экземпляра по умолчанию. Если это неизбежно, я бы просто установил константу.
DEFAULT_EXAM_ID = 1
class Student(models.Model):
...
exam_taken = models.ForeignKey("Exam", default=DEFAULT_EXAM_ID)
Меньший код, и именование константы делает его более читаемым.
Ответ 2
Я использую естественные ключи для принятия более естественного подхода:
<app>/models.py
from django.db import models
class CountryManager(models.Manager):
"""Enable fixtures using self.sigla instead of `id`"""
def get_by_natural_key(self, sigla):
return self.get(sigla=sigla)
class Country(models.Model):
objects = CountryManager()
sigla = models.CharField(max_length=5, unique=True)
def __unicode__(self):
return u'%s' % self.sigla
class City(models.Model):
nome = models.CharField(max_length=64, unique=True)
nation = models.ForeignKey(Country, default='IT')
Ответ 3
Вы можете использовать этот шаблон:
class Other(models.Model):
DEFAULT_PK=1
name=models.CharField(max_length=1024)
class FooModel(models.Model):
other=models.ForeignKey(Other, default=Other.DEFAULT_PK)
Конечно, вы должны быть уверены, что в таблице Other
есть строка. Вы должны использовать datamigration, чтобы быть уверенным, что он существует.
Ответ 4
В моем случае я хотел установить значение по умолчанию для любого существующего экземпляра связанной модели. Поскольку возможно, что Exam
с id 1
был удален, я сделал следующее:
class Student(models.Model):
exam_taken = models.ForeignKey("Exam", blank=True)
def save(self, *args, **kwargs):
try:
self.exam_taken
except:
self.exam_taken = Exam.objects.first()
super().save(*args, **kwargs)
Если exam_taken
не существует, django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist
будет поднят при попытке получить к нему доступ.