Django: значение поля по умолчанию из экземпляров собственной модели - PullRequest
18 голосов
/ 26 августа 2010

Как сделать значение по умолчанию для поля, которое будет взято из существующих объектов модели?

Я попробовал это, и это не сработало:

1)

class ModelA(models.Model):
    fieldA = models.CharField(default=self.get_previous())

    def get_previous(self):
        return ModelA.objects.all()[0].fieldA

NameError: name 'self' is not defined

2)

class ModelA(models.Model):
    fieldA = models.CharField(default=ModelA.get_previous())

    @staticmethod
    def get_previous():
        return ModelA.objects.all()[0].fieldA

NameError: name 'ModelA' is not defined

3) * +1017 *

class ModelA(models.Model):
    fieldA = models.CharField(default=get_previous())

def get_previous():
    return ModelA.objects.all()[0].fieldA

NameError: global name 'get_previous' is not defined

4)

def get_previous():
    return ModelA.objects.all()[0].fieldA

class ModelA(models.Model):
    fieldA = models.CharField(default=get_previous())

NameError: global name 'ModelA' is not defined

Мне понятно, почему 3) и 4) не будут работать. Я могу себе представить, почему 1) не будет работать - похоже, свойства класса не могут ссылаться на свойства экземпляра (т.е. на себя). Я могу представить себе, почему 2) не будет работать - очевидно, что нет никакой ссылки на ModelA, пока интерпретатор не пройдет весь класс.

Так как мне подойти к этому?

Ответы [ 3 ]

16 голосов
/ 26 августа 2010

В ваших примерах нужно убрать оператор вызова ().

В настоящее время оператор выполняется сразу при первом цикле чтения-анализа. Указав вместо этого имя символа, класс Django получает указатель на функцию, который он будет выполнять, когда ему действительно потребуется значение по умолчанию.

Примером становится:

def get_previous():
    return ModelA.objects.all()[0].fieldA

class ModelA(models.Model):
    fieldA = models.CharField(default=get_previous)

Если вы собираетесь сделать это для большого количества полей, рассмотрите возможность переопределения функции save, поэтому вам нужно только один раз извлечь предыдущий объект из базы данных.

3 голосов
/ 26 августа 2010

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

Вариант 2: Переопределить метод сохранения модели и закодировать там проверку - если поле A имеет значение None, то ввести в него некоторое значение. Этот вариант лучше, если вы хотите, чтобы значение по умолчанию работало на уровне данных, а не только как значения по умолчанию для формы (т. Е. Также для экземпляров, которые вы создаете другими способами).

3 голосов
/ 26 августа 2010

Если вы хотите просто вывести значение по умолчанию, переопределите метод __getattr__() следующим образом:

class ModelA(models.Model):
  # your fields
  def __getattr__(self, name):
    if(name == 'fieldA' and !self.fieldA):
      return self.get_previous()
    else:
      return super(ModelA, self).__getattr__(name)

Сохранение значения по умолчанию из объекта будет немного сложнее. Первое решение, которое приходит мне в голову, переопределить save() метод (я считаю, что есть более простое решение)

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