Подтвердить что ты не робот

Django: значение поля по умолчанию из экземпляров собственной модели

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

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

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)

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) не сработает - похоже, что свойства класса не могут ссылаться на экземпляр (т.е. Self). Я могу себе представить, почему 2) не будет работать - видимо, нет ссылки на ModelA, пока интерпретатор не пойдет по всему классу.

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

4b9b3361

Ответ 1

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

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

Пример:

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

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

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

Ответ 2

Если вы хотите просто вывести значение по умолчанию, переопределите метод __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() (я считаю, что есть более простое решение)

Ответ 3

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

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