문제

보고서를 생성하는 데 사용되는 쿼리(시작 날짜, 종료 날짜 등)를 제어하는 ​​필드에 대해 Django 양식(새 양식)을 사용하는 웹 보고서가 있습니다.내가 겪고 있는 문제는 페이지가 양식의 초기 값(바인딩되지 않음)을 사용하여 작동해야 하지만 is_valid()를 호출하지 않으면 clean_data 필드에 액세스할 수 없다는 것입니다.그러나 is_valid()는 바인딩되지 않은 양식에서는 항상 실패합니다.

Django의 양식은 바인딩되지 않은 양식이 HTML을 표시하는 것 외에는 실제로 유용하지 않은 데이터 편집의 사용 사례로 설계된 것 같습니다.

예를 들어 다음과 같은 경우가 있습니다.

if request.method == 'GET':
    form = MyForm()
else:
    form = MyForm(request.method.POST)

if form.is_valid():
    do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

is_valid()는 이것이 GET인 경우(바인딩되지 않았기 때문에) 실패할 것이며, 그렇게 하면:

if request.method == 'GET':
    form = MyForm()
    do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])
else:
    form = MyForm(request.method.POST)
    if form.is_valid():
       do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

do_query에 대한 첫 번째 호출은 is_valid()가 호출되지 않았기 때문에 유효한 필드가 아닌 form.cleaned_data에서 예외를 트리거합니다.다음과 같이 해야 할 것 같습니다.

if request.method == 'GET':
    form = MyForm()
    do_query(form['start_date'].field.initial, form['end_date'].field.initial)
else:
    form = MyForm(request.method.POST)
    if form.is_valid():
       do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

즉, 바인딩된 양식과 바인딩되지 않은 양식 사이에서 양식 값을 검색하기 위한 공통 인터페이스가 없습니다.

누구든지 이 작업을 수행하는 더 깨끗한 방법을 보나요?

도움이 되었습니까?

해결책

이 메소드를 양식 클래스에 추가하는 경우:

def get_cleaned_or_initial(self, fieldname):
        if hasattr(self, 'cleaned_data'):
            return self.cleaned_data.get(fieldname)
        else:
            return self[fieldname].field.initial

그런 다음 코드를 다음과 같이 다시 작성할 수 있습니다.

if request.method == 'GET':
    form = MyForm()
else:
    form = MyForm(request.method.POST)
    form.is_valid()

do_query(form.get_cleaned_or_initial('start_date'), form.get_cleaned_or_initial('end_date'))

다른 팁

매여 있지 않은 이는 양식(초기 또는 나중에 제공됨)과 연관된 데이터가 없으므로 유효성 검사가 실패할 수 있음을 의미합니다.다른 답변(그리고 자신의 결론)에서 언급했듯이 초기 값을 제공하고 바인딩된 데이터와 초기 값을 모두 확인해야 합니다.

양식의 사용 사례는 양식 처리입니다. 그리고 유효성 검사이므로 액세스하기 전에 유효성을 검사할 일부 데이터가 있어야 합니다. cleaned_data.

초기값 사전을 양식에 전달할 수 있습니다.

if request.method == "GET":
    # calculate my_start_date and my_end_date here...
    form = MyForm( { 'start_date': my_start_date, 'end_date': my_end_date} )
...

참조 공식 양식 API 문서, 그들은 이것을 보여줍니다.

편집하다:다른 사용자의 답변에 따르면 아마도 이것이 가장 깨끗한 솔루션일 것입니다.

if request.method == "GET":
    form = MyForm()
    form['start_date'] = form['start_date'].field.initial
    form['end_date'] = form['end_date'].field.initial
else:
    form = MyForm(request.method.POST)
if form.is_valid():
    do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

나는 이것을 시도하지 않았습니다.누군가 이것이 작동하는지 확인할 수 있습니까?나는 이것이 새로운 메소드를 생성하는 것보다 낫다고 생각합니다. 왜냐하면 이 접근 방식은 새로운 '마법의' 접근자에 대해 알기 위해 다른 코드(당신이 작성하지 않았을 수도 있음)를 요구하지 않기 때문입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top