폼이 초기화 된 후 Django 설정 필드 값


116

양식이 초기화 된 후 필드를 특정 값으로 설정하려고합니다.

예를 들어, 다음 클래스가 있습니다.

class CustomForm(forms.Form):
    Email = forms.EmailField(min_length=1, max_length=200)

보기에서 다음과 같이 할 수 있기를 원합니다.

form = CustomForm()
form["Email"] = GetEmailString()

return HttpResponse(t.render(c))

답변:


135

POST 데이터를 전달하지 않기 때문에 수행하려는 작업은 양식에 표시 될 초기 값을 설정하는 것이라고 가정합니다. 이를 수행하는 방법은 initial키워드를 사용하는 것입니다.

form = CustomForm(initial={'Email': GetEmailString()})

자세한 설명 은 Django Form 문서 를 참조하십시오 .

양식을 제출 한 후 값을 변경하려는 경우 다음과 같이 사용할 수 있습니다.

if form.is_valid():
    form.cleaned_data['Email'] = GetEmailString()

사용에 대한 자세한 내용은 위의 참조 문서를 확인하십시오. cleaned_data


2
내가 아는,하지만이 확인한다 내 ModelChoiceField아직도 내가 그에게 줄 때 invalid_choice을주고있다 initial값 :(
markwalker_

네, 이것도 제 문제입니다. 그리고 form.data [ 'Email'] 변경은 불가능합니다.
GergelyPolonkai 2015 년

2
난에 광산을 변경 form.data['Email'] = GetEmailString()하고 그것을 작동
psychok7을

1
CustomForm (request.POST)와 .is_valid () 사이 에 설정해야 하므로 생성자에서 이니셜도 사용할 수없고 clean_data도 사용할 수 없습니다. form.data를 사용해 보았지만 변경 불가능합니다 (Django 1.11).
Teekin

이 질문에 대한 올바른 해결책은 다음과 같습니다. form.fields['Email'].initial = GetEmailString() The form.fields['keyword'].initial는 양식을 인스턴스화 한 후에도 값을 초기화 할 수있는 액세스 권한을 제공합니다
vctrd

95

이미 양식을 초기화 한 경우 필드의 초기 속성을 사용할 수 있습니다. 예를 들면

form = CustomForm()
form.fields["Email"].initial = GetEmailString()

또한 formset이있는 for 루프에서도 잘 작동합니다. "for form in formset"논리를 사용하면 위에서 본 것처럼 선택 항목과 초기 데이터를 설정할 수 있습니다.
radtek 2014-08-26

5
이를 수행하는 다른 방법이 Django 1.7 / Python 3.4입니까? 이것은 나를 위해 작동하지 않습니다
제레미

1
@JeremyCraigMartinez : 아니요 ... 바운드 양식을 시도중인 양식 (GET / POST 데이터가 전달됨)입니까? 문서 는 이것이 바인딩되지 않은 양식에 대해서만 초기 값이 표시되는 이유 라고 말합니다 . 바인딩 된 양식의 경우 HTML 출력은 바인딩 된 데이터를 사용합니다. 참조 여기에
마커스

9
정확한 방법은 [ "이메일"= GetEmailString () form.initial 인
엘리오 Scordo

12

__init__어떤 이유로 폼의 메서드 내에서 수행 하려면 initialdict를 조작 할 수 있습니다 .

class MyForm(forms.Form):
    my_field = forms.CharField(max_length=255)

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.initial['my_field'] = 'Initial value'

마침내 해결책을 찾았습니다. 감사합니다. 그것은 나를 위해 일했습니다.
Almas Dusal

8

수집 된 양식 데이터 세트의 사본 에 데이터를 추가하는 경우 Nigel Cohen과 같은 것이 작동합니다 .

form = FormType(request.POST)
if request.method == "POST":
    formcopy = form(request.POST.copy())
    formcopy.data['Email'] = GetEmailString()

1
저는 원시 데이터를 재정의하는 것을 좋아하지 않습니다. 이 작업 data[form.add_prefix('Email')]을 반드시 수행해야하는 경우 접두사가 설정된 경우를 고려해야합니다.
Josh

2
이를 수행하는 다른 방법이 Django 1.7 / Python 3.4입니까? 이것은 나를 위해 작동하지 않습니다
제레미

세 번째 줄은 원래 형식을 유지할 필요가없는 경우 약간 더 짧을 수 있습니다.form.data = form.data.copy()
ZZY

@Josh, 여기에 필요한 시나리오가 하나 있습니다. 양식을 사용하여 입력 유효성 검사-> 입력 처리-> 처리 완료-> 양식의 여러 필드를 지우거나 수정하고 응답으로 HTML로 렌더링합니다. 예를 들어, 양식에 '이름', '이메일', '내용'필드가 있는데, '이름'과 '이메일'은 유지하고 싶지만 '내용'은 지 웁니다. 따라서 사용자가 다른 POST를 제출하려는 경우 이름 / 이메일을 다시 입력 할 필요가 없습니다. 물론 초기 값과 동일한 이름 / 이메일로 새 양식을 초기화하는 것이 한 가지 방법이지만 경우에 따라 이전 양식을 지우는 것이 더 간단하다고 생각합니다
ZZY

내가 완전히 이해했는지 잘 모르겠습니다. 그러나 내가 그렇게한다면 대신 modelform_factory. 이렇게하면 원하지 않는 필드가없는 Form 클래스를 생성 할 수 있습니다. 양식 개체가 렌더링되지 않은 필드에 대한 데이터를 계속 허용하므로 렌더링되지 않은 필드가있는 Form 클래스를 사용하는 것은 매우 위험합니다. 공격자는이를 유리하게 사용할 수 있습니다.
Josh

5

다음과 같이 양식을 초기화 한 경우

form = CustomForm()

2019 년 1 월 현재 올바른 방법 .initial은 데이터를 대체하는 데 사용 하는 것입니다. 이것은 intial양식과 함께 dict 의 데이터를 대체합니다 . 다음과 같은 일부 인스턴스를 사용하여 초기화 한 경우에도 작동합니다. form = CustomForm(instance=instance)

양식의 데이터를 바꾸려면 다음을 수행해야합니다.

form.initial['Email'] = GetEmailString()

이것을 일반화하면,

form.initial['field_name'] = new_value

3

Form.data 필드를 변경하십시오.

class ChooseProjectForm(forms.Form):
    project = forms.ModelChoiceField(queryset=project_qs)
    my_projects = forms.BooleanField()

    def __init__(self, *args, **kwargs):
        super(ChooseProjectForm, self).__init__(*args, **kwargs)
        self.data = self.data.copy()  # IMPORTANT, self.data is immutable
        # any condition:
        if self.data.get('my_projects'):
            my_projects = self.fields['project'].queryset.filter(my=True)
            self.fields['project'].queryset = my_projects
            self.fields['project'].initial = my_projects.first().pk
            self.fields['project'].empty_label = None  # disable "-----"
            self.data.update(project=my_projects.first().pk)  # Update Form data
            self.fields['project'].widget = forms.HiddenInput()  # Hide if you want

0

믹스에 또 다른 방법을 던져 보자 : 이것도 좀 더 현대적인 표기법으로 작동한다. a QueryDict가 불변 이라는 사실을 중심으로 작동합니다 .

>>> the_form.data = {**f.data.dict(), 'some_field': 47}
>>> the_form['some_field'].as_widget()
'<input type="hidden" name="some_field" value="47"
        class="field-some_field" id="id_some_field">'

0

위젯에서 '값'속성을 사용하십시오. 예:

username = forms.CharField(
    required=False,
    widget=forms.TextInput(attrs={'readonly': True, 'value': 'CONSTANT_VALUE'}),
)

-12

이를 수행하는 또 다른 방법은 이미 양식 (데이터 포함 또는 제외)을 초기화했으며 표시하기 전에 데이터를 추가해야하는 경우입니다.

form = Form(request.POST.form)
form.data['Email'] = GetEmailString()

8
이것은 나를 위해 실패합니다. 나는 내 양식의에서 위의 같은 라인이 초기화 방법을, 그리고 제기 "AttributeError :이 QueryDict 인스턴스는 불변이다"
조나단 하틀리

이 코드는 양식 데이터없이 양식이 초기화 된 경우에만 작동합니다. 결과적으로 request.GET 또는 request.POST와 같은 변경 불가능한 객체는 바인딩되지 않으므로 오류없이 변경할 수있는 빈 사전 (form.data)을 얻게됩니다. 참고로 나는 장고 1.6.3 사용하고 있습니다
potar

"Content-Type"헤더가 "multipart / form-data"로 설정된 경우 작동합니다. "application / x-www-form-urlencoded"의 컨텐츠 유형을 사용하면 실패합니다. 이유는 모르겠지만 디버그하는 것은 *****였습니다.
teewuane
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.