Старый вопрос, но добавление описательного ответа, так как я считаю, что это будет полезно для какого-то нового разработчика.
Я также пытался с self
. base_fields
, нобезрезультатно: в форме всегда отображается значение базы данных.Любые идеи?
Если форма является «инициализированной» формой, либо: -
с использованием аргумента initial
(например, YourModelFrom(initial={'filed1': variable})
- как правило,случай, когда вы хотите передать динамически рассчитанные начальные значения для некоторых полей).Ссылка Setting Initial Values
или
с использованием аргумента instance
(например, YourModelFrom(instance=model_object)
- обычно тот случай, когда вы хотите обновитьсуществующий объект экземпляра модели).Ссылки читайте в ModelFrom save() method
Примечание:
1 `ModelFrom` класс наследует ` BaseModelFrom` класс.Класс BaseModelFrom` наследует `BaseForm` class.
2 Аргумент instance
добавляется в ` BaseModelFrom` конструктор класса, когда мы назначаемобъект экземпляра класса модели для аргумента instance
(следовательно, instance is not None
), затем `BaseModelFrom` вызывает конструктор model_to_dict()
и обновляет аргумент initial
перед вызовом конструктора суперкласса.Проверьте def __init__
в классе BaseModelFrom
Затем явное присвоение начального значения полю (как показано в рассматриваемом коде OP) не действует,это связано с тем, что метод _clean_fields
записан в классе BaseFrom
.
Code Snip:
def _clean_fields(self):
for name, field in self.fields.items():
value = field.widget.value_from_datadict(
self.data, self.files, self.add_prefix(name))
try:
if isinstance(field, FileField):
initial = self.initial.get(name, field.initial) # <- Check
value = field.clean(value, initial)
else:
Согласно строке кода initial = self.initial.get(name, field.initial)
, если начальное значение для поля задано в initial
dict, тогда значение, присвоенное field.initial
, равно , а не используется.
[ОТВЕТ] :
Хотя, ответ @Daniel является совершенно правильным, но можно также использовать другой способ достижения того же эффекта, используя self.initial
:
def __init__(self, *args, **kwargs):
super(ArtefactForm, self).__init__(*args, **kwargs)
self.initial['material'] = 'Test'
Попробуй !!
self.initial
- это не что иное, как диктат, который мы передаем в качестве аргумента.Проверьте код __init__
в BaseForm
:
class BaseForm(object):
def __init__(........
........):
:
self.prefix = prefix
self.initial = initial or {} # <-- Notice
self.error_class = error_class
:
Примечание: я не нашел никакой документации, связанной с использованием начального атрибута, я просто исследовал базовый код и использовал его.
Редактировать: поведение, о котором сообщается в Вопросе, также задокументировано в Django Model
Форма.initial
Обратите внимание, что если Field
определяет initial
и , вы включаете initial
при создании экземпляра формы, тогда последний initial
будет иметь приоритет.В этом примере initial
предоставляется как на уровне поля, так и на уровне экземпляра формы, и последний получает приоритет:
>>> from django import forms
>>> class CommentForm(forms.Form):
... name = forms.CharField(initial='class')
... url = forms.URLField()
... comment = forms.CharField()
>>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
>>> print(f)
<tr><th>Name:</th><td><input type="text" name="name" value="instance" />
<tr><th>Url:</th><td><input type="url" name="url" /></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
PS:Кстати, пункт 2 в моих ответах говорит о разнице между аргументами initial
и instance
.Это еще один аргумент ключ-значение data
- значения в этом триггере формируют проверки.Прочитайте это Разница между начальной формой и связанными данными Django? .