Установка значения по умолчанию для атрибута внешнего ключа - PullRequest
53 голосов
/ 16 февраля 2012

Каков наилучший способ установить значение по умолчанию для поля внешнего ключа в модели? Предположим, у меня есть две модели: Студент и Экзамен со студентом, имеющим в качестве внешнего ключа 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)

С здесь , но не с таблицами не существует ошибки при синхронизации.

Любая помощь будет оценена.

Ответы [ 5 ]

32 голосов
/ 16 февраля 2012

В обоих ваших примерах вы жестко программируете идентификатор экземпляра по умолчанию. Если это неизбежно, я бы просто установил константу.

DEFAULT_EXAM_ID = 1
class Student(models.Model):
    ...
    exam_taken = models.ForeignKey("Exam", default=DEFAULT_EXAM_ID)

Меньше кода и присвоение имени константе делают его более читабельным.

10 голосов
/ 21 января 2014

Я использую естественные ключи, чтобы принять более естественный подход:

<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')
7 голосов
/ 14 августа 2018

Я бы немного изменил ответ @ vault выше (это может быть новая функция). Обязательно желательно ссылаться на поле под естественным именем. Однако вместо переопределения Manager я бы просто использовал to_field параметр ForeignKey:

class Country(models.Model):
    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, to_field='sigla', default='IT')
6 голосов
/ 26 ноября 2016

В моем случае я хотел установить значение по умолчанию для любого существующего экземпляра связанной модели.Поскольку возможно, что Exam с идентификатором 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 будет вызвано, когдапытаясь получить к нему доступ.

4 голосов
/ 04 июня 2014

Вы можете использовать этот шаблон:

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. Вы должны использовать миграцию данных, чтобы убедиться, что она существует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...