Как использовать значения формы из несвязанной формы

StackOverflow https://stackoverflow.com/questions/75621

  •  09-06-2019
  •  | 
  •  

Вопрос

У меня есть веб-отчет, который использует форму Django (новые формы) для полей, которые управляют запросом, используемым для создания отчета (дата начала, дата окончания, ...).Проблема, с которой я сталкиваюсь, заключается в том, что страница должна работать с использованием начальных значений формы (несвязанных), но я не могу получить доступ к полю cleaned_data, если не вызову is_valid().Но 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 вызывает исключения для form.cleaned_data, которое не является допустимым полем, поскольку is_valid() не был вызван.Похоже, я должен сделать что-то вроде:

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'])

то есть, не существует общего интерфейса для получения значений формы между связанной формой и несвязанной.

Кто-нибудь видит более чистый способ сделать это?

Это было полезно?

Решение

Если вы добавите этот метод в свой класс form:

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