Ответ 1
Попробуйте следующее:
def __init__(self, *args, **kwargs):
initial = kwargs.get('initial', {})
initial['material'] = 'Test'
kwargs['initial'] = initial
super(ArtefactForm, self).__init__(*args, **kwargs)
в моем проекте Django (1.2), я хочу предварительно заполнить поле в modelform, но мое новое значение игнорируется. Это фрагмент:
class ArtefactForm(ModelForm):
material = CharField(widget=AutoCompleteWidget('material', force_selection=False))
def __init__(self, *args, **kwargs):
super(ArtefactForm, self).__init__(*args, **kwargs)
self.fields['material'].initial = 'Test'
Я также пробовал с self.base_fields
, но никакого эффекта: всегда всегда отображается значение базы данных в форме. Любые идеи?
Попробуйте следующее:
def __init__(self, *args, **kwargs):
initial = kwargs.get('initial', {})
initial['material'] = 'Test'
kwargs['initial'] = initial
super(ArtefactForm, self).__init__(*args, **kwargs)
Старый вопрос, но добавление описательного ответа, поскольку я считаю, что это было бы полезно для некоторых новых разработчиков.
Я также пробовал с
self
.base_fields
, но никакого эффекта: всегда всегда отображается значение базы данных в форме. Любые идеи?
Если форма является "инициализированной" формой, либо: -
используя аргумент initial
(например, YourModelFrom(initial={'filed1': variable})
— обычно это случай, когда вы хотите передать динамически рассчитанные начальные значения для некоторых полей). Ссылка Setting Initial Values
или
с использованием аргумента instance
(например. YourModelFrom(instance=model_object)
— обычно это случай, когда вы хотите обновить существующий экземпляр объекта). Ссылки читайте ModelFrom save() method
<суб > Примечание:
1 класс ModelFrom наследует класс `BaseModelFrom`, Класс ` BaseModelFrom` наследует ` BaseForm` класс.
2 Аргумент instance
добавляется в конструктор класса ` BaseModelFrom`, когда мы присваиваем объект экземпляра класса модели аргументу instance
(следовательно, instance is not None
), затем конструктор конструктора` BaseModelFrom` model_to_dict()
и обновляет аргумент initial
до вызова суперклассического класса. Проверьте def __init__
в классе BaseModelFrom
Тогда присвоение начального значения ядру явно (как показано в соответствующем OP-коде) не влияет, это связано с тем, что _clean_fields
метод написан в классе BaseFrom
.
Код 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
Динамические начальные значения
Form.initial
Обратите внимание, что если a
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: Btw, пункт 2 в моих ответах указывает разницу между аргументами initial
и instance
. Это еще один аргумент ключа-значения data
- значения в том, что триггеры формируют валидации. прочитайте эту Разницу между Django Form 'initial' и 'bound data'?.
Суб >