Установка начального значения поля формы Django в методе __init__

Джанго 1.6

У меня есть рабочий блок кода в классе формы Django, как показано ниже. Набор данных, из которого я строю список полей формы, может включать начальное значение для любого из полей, и мне не удается установить это начальное значение в форме. Блок if field_value: ниже действительно заполняет начальный атрибут словаря формы, но начальное значение не отображается. Обратите внимание, что (если вам интересно) атрибут .initial не существует до вызова super().

Можно ли это сделать?

Если да, то что я делаю не так, чтобы это сработало?

Спасибо!

def __init__(self, *args, **kwargs):
    id = kwargs.pop('values_id', 0)
    super(LaunchForm, self).__init__(*args, **kwargs)
    # Lotsa code here that uses the id value
    # to execute a query and build the form
    # fields and their attributes from the 
    # result set

    if field_value:
        self.initial[field_name] = field_value

person Steve Sawyer    schedule 13.03.2014    source источник
comment
Моя проблема заключалась в том, что я вызывал super.__init после установки self.initial... Блин!   -  person MagicLAMP    schedule 07.09.2017


Ответы (6)


У меня была точно такая же проблема, и я решил ее следующим образом:

def __init__(self, *args, **kwargs):
    instance = kwargs.get('instance', None)

    kwargs.update(initial={
        # 'field': 'value'
        'km_partida': '1020'
    })

    super(ViagemForm, self).__init__(*args, **kwargs)

    # all other stuff
person Victor Guimarães Nunes    schedule 12.11.2014

Попробуйте так:

super(ViagemForm, self).__init__(*args, **kwargs)

if field_value:
    #self.initial[field_name] = field_value
    self.fields[field_name].initial = field_value
person ndpu    schedule 13.03.2014
comment
@ndpu - спасибо, но это тоже не работает - объект поля существует, и у него есть атрибут данных initial, для которого действительно установлено начальное значение, но он не отображается в форме. @karthikr - код, который устанавливает поля формы, выполняется ПОСЛЕ вызова super (), и только после выполнения этого кода я знаю, какими должны быть начальные значения (я). Я также пробовал `self.initial.update({field_name: field_value})', но это также оставляет поле пустым на странице. Я также попытался установить начальный аргумент поля как часть определения поля - безуспешно с таким подходом. - person Steve Sawyer; 14.03.2014
comment
Что ж. я использую точно такой же код, как я показал в ответе, и он работает для меня. - person karthikr; 15.03.2014
comment
@karthikr - Я предполагаю, что ваш работает, потому что вы вызываете super() после установки свойства. Играть с этим в пятницу стало еще интереснее — я могу не только убедиться, что начальное значение существует, но и является обязательным полем, и наличие значения приводит к тому, что форма передает is_valid() в метод представления post()! Итак, я получаю худшее из всего - значение есть и проверено, но не отображается в форме! - person Steve Sawyer; 17.03.2014
comment
Я не приблизился к тому, чтобы заставить это работать так, как мне нужно, но я делаю пару открытий, и ошибка может заключаться не в том, как я заполняю начальное значение, а в поведении тип поля (или мое понимание этого поведения). Я собираюсь опубликовать новую тему, которая касается этого аспекта проблемы. Спасибо за все Ваши ответы. - person Steve Sawyer; 17.03.2014
comment
вы должны сначала инициализировать форму с super, чтобы сделать self.fields доступным - person biodiv; 06.06.2016
comment
Сначала я сделал super, а затем внес изменения, и он устанавливает значение поля выбора в первый доступный вариант. Не работает для меня - person Julio Marins; 31.07.2017

Я хочу упомянуть, хотя это может не решить вашу проблему, что «начальный» dict kwarg, отправленный в форму, имеет предпочтение перед field['field_name'].initial.

class MyView(View):
    form = MyForm(initial={'my_field': 'first_value'})

class MyForm(Form):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['my_field'].initial = 'second_value'

Для рендеринга my_field изначально будет установлено значение 'first_value'.

Некоторые варианты (среди прочего) могут быть:

Определите second_value в представлении перед инициализацией формы:

class MyView(View):
    # determine second_value here
    form = MyForm(initial={'my_field': 'second_value'})

замените first_value на second_value в initial перед вызовом super():

class MyForm(Form):
    def __init__(self, *args, **kwargs):
        # determine second_value here
        if kwargs.get('initial', None):
            kwargs['initial']['my_field'] = 'second_value'
        super().__init__(*args, **kwargs)

Перед вызовом super() убедитесь, что 'first_value' не находится в kwargs['initial']:

class MyForm(Form):
    def __init__(self, *args, **kwargs):
        if kwargs.get('initial', None):
            if kwargs['initial']['my_field']
                del(kwargs['initial']['my_field']
        super().__init__(*args, **kwargs)
        # determine second_value here
        self.fields['my_field'].initial = 'second_value'
person Megan Word    schedule 04.10.2017

У меня была похожая проблема с установкой начального значения для переключателя под названием «needs_response» и решить ее, проверив атрибуты self и сославшись на «declared_fields»:

    # views.py
    def review_feedback_or_question(request, template, *args, **kwargs):
        if 'fqid' in kwargs:
            fqid = kwargs['fqid']
        submission = FeedbackQuestion.objects.get(pk=fqid)
        form = FeedbackQuestionResponseForm(submission_type=submission.submission_type)
        # other stuff

    # forms.py
    class FeedbackQuestionResponseForm(forms.Form):
        CHOICES = (('1', 'Yes'), ('2', 'No'))
        response_text = forms.CharField(
            required=False,
            label='',
            widget=forms.Textarea(attrs={'placeholder': 'Enter response...'}))
        needs_response = forms.ChoiceField(choices=CHOICES,
            label='Needs response?',
            widget=forms.RadioSelect())
        def __init__(self, *args, **kwargs):
            if 'submission_type' in kwargs:
                submission_type = kwargs.pop('submission_type')
                if submission_type == 'question':
                    self.declared_fields['needs_response'].initial = 1
                else:
                    self.declared_fields['needs_response'].initial = 2
            super(FeedbackQuestionResponseForm, self).__init__(*args, **kwargs)
person Jim    schedule 03.12.2015

Это работает:

class BarForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['state'] = forms.ChoiceField(
            required=False,
            choices=Foo.ADDRESS_STATE_CHOICES,
            disabled='disabled',
            initial='xyz',
        )

    state = forms.ChoiceField(
        label='State',
        choices=Foo.ADDRESS_STATE_CHOICES,
        initial='foo',
    )
person Julio Marins    schedule 31.07.2017

Сделайте initial= "" в определении поля, чтобы решить вашу проблему. Оба предложенных метода верны, вам нужно просто определить initial= "" в поле определения, и проблема решена.

person Hehe    schedule 09.05.2020