Как сделать значение по умолчанию для поля, которое будет взято из существующего объекты модели?
Я пробовал это, и это не сработало:
1)
class ModelA(models.Model):
fieldA = models.CharField(default=self.get_previous())
def get_previous(self):
return ModelA.objects.all()[0].fieldA
NameError: имя 'self' не определено
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 не определено
3)
class ModelA(models.Model):
fieldA = models.CharField(default=get_previous())
def get_previous():
return ModelA.objects.all()[0].fieldA
NameError: глобальное имя 'get_previous' не определено
4)
def get_previous():
return ModelA.objects.all()[0].fieldA
class ModelA(models.Model):
fieldA = models.CharField(default=get_previous())
NameError: глобальное имя 'ModelA' не определено
I понятно, почему 3) и 4) не сработает Я могу себе представить, почему 1) не будет работать - похоже, свойства класса не могут ссылаться на свойства экземпляра (то есть на себя). Я могу себе представить, почему 2) не будет работать - очевидно, что нет никакой ссылки на ModelA, пока интерпретатор не пройдет через весь класс.
Так как мне подходить к этому?
В ваших примерах вам нужно удалить оператора вызова ()
.
В настоящее время оператор выполняется сразу же при первом цикле чтения-анализа. Указав вместо этого имя символа, класс Django получает указатель на функцию, которую он выполнит, когда ему действительно понадобится значение по умолчанию.
Пример выглядит следующим образом:
def get_previous():
return ModelA.objects.all()[0].fieldA
class ModelA(models.Model):
fieldA = models.CharField(default=get_previous)
Если вы собираетесь сделать это для большого количества полей, рассмотрите возможность переопределения функции save
, чтобы вам нужно было получить предыдущий объект из базы данных только один раз. .
Если вы хотите просто вывести значение по умолчанию, переопределите метод __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()
метод (думаю, есть более простое решение)
Вариант 1: Использовать типовые формы. Это формы, основанные на моделях, значения которых можно легко заполнить значениями из конкретного экземпляра. Эта опция хороша, если вы хотите, чтобы значение по умолчанию отображалось пользователю в формах.
Вариант 2: Переопределите метод сохранения модели и закодируйте там проверку - если поле A равно None, то поместите в него какое-то значение. Этот вариант лучше, если вы хотите, чтобы значение по умолчанию работало на уровне данных, а не только как значение по умолчанию формы (т. е. также для экземпляров, которые вы создаете другими способами).