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

Переопределение начального значения в ModelForm

в моем проекте 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, но никакого эффекта: всегда всегда отображается значение базы данных в форме. Любые идеи?

4b9b3361

Ответ 1

Попробуйте следующее:

def __init__(self, *args, **kwargs):
    initial = kwargs.get('initial', {})
    initial['material'] = 'Test'
    kwargs['initial'] = initial
    super(ArtefactForm, self).__init__(*args, **kwargs)

Ответ 2

Старый вопрос, но добавление описательного ответа, поскольку я считаю, что это было бы полезно для некоторых новых разработчиков.

Я также пробовал с 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'?. Суб >