2010-11-27 3 views
7

Я положил Javascript на стороне клиента в свой шаблон, который позволяет пользователю динамически добавлять поля в форму. Моя проблема в том, что эти поля очищаются в form.cleaned_data, поэтому я не могу обращаться к ним таким образом.Динамически добавленные поля формы удаляются в form.cleaned_data

Все поля доступны в request.POST, поэтому я мог бы решить эту проблему с этим, но я хочу сделать это «правильным способом», и я думаю, что решение лежит где-то в использовании форм django, а не при чтении запроса непосредственно.

Я пробовал переопределить form.clean(), но, похоже, данные уже ушли к тому времени, когда они туда попали.

Другие данные: Я назвал эти поля fieldname_x, где x - это номер. В request.POST, request.POST['fieldname'] - это список всех значений, но form.cleaned_data содержит только последнее значение каждого списка.

ответ

2

Знаете ли вы, какие типы этих полей будут заранее? Являются ли они просто текстовыми полями? Я сделал что-то похожее на это, создавая динамические формы.

# make sure these exist by examining request.POST 
custom_fields = ['fieldname_1', 'fieldname_2'] 

attrs = dict((field, forms.CharField(max_length=100, required=False)) 
      for field in custom_fields) 
DynamicForm = type("DynamicForm", (YourBaseForm,), attrs) 
submitted_form = DynamicForm(request.POST) 

Ваша поданная форма должна содержать все необходимые вам поля вместе с их значениями. Возможно, вы захотите удалить required = False, но это зависит от вас.

Что это такое, выполняет динамический подкласс вашей базовой формы, добавляя атрибуты, переданные как attrs в определение класса. Поэтому, когда вы создаете экземпляр с данными post, они должны отображаться правильно.

Edit:

Я немного более внимательно прочитать вопрос. То, что вы хотите сделать, это убедиться, что ваши динамические элементы ввода названы правильно, и значения соответствуют этим именам полей, когда они достигают джанго. В противном случае request.POST не заполнит форму правильно.

<input type='text' name='fieldname_1' value='value_for_field_1' /> 

и т.д.

0

Я делаю это в проекте я сейчас работаю. Вам нужно взглянуть на формы. Но будьте осторожны, это некрасиво. Вы должны изменить это глупое скрытое поле, которое хранится в счетчике формы, и вам нужно правильно переименовать входы. Это связано с большим количеством бессмысленного синтаксического анализа строк. Если бы они использовали массивы, как PHP, не было бы проблемой, но они одержима делает мою жизнь несчастной ... бродит от

Edit: http://docs.djangoproject.com/en/dev/topics/forms/formsets/#empty-form они обеспечивают это, что делает ваша жизнь на 5% менее болезненна ... вы можете просто найти и заменить на префикс с соответствующим номером .. но я думаю, что у меня была проблема, когда пустая форма не содержит правильных значений по умолчанию, если вы инициализируете form с данными post, поэтому мне пришлось создать второй экземпляр без данных post на пустую пустую_формацию, которая просто задерживается.

+0

Ральфа, я предположил бы, что вы пошли об этом длинном пути. Использовать python и систему Django. Динамически создавать модели и формы там, где это необходимо. См. Мой ответ. – 2010-11-28 01:01:36

2

Также возможно выполнить эту работу в файле формы, вот отличная демонстрация Джейкоба Каплана-Моссе для динамических форм: http://jacobian.org/writing/dynamic-form-generation/, который достаточно хорошо подходит для этой проблемы.

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

class MyForm(forms.Form): 
    text = forms.CharField(max_length=30) 

    def __init__(self, *args, **kwargs): 
     extra = kwargs.pop('extra') 
     super(MyForm, self).__init__(*args, **kwargs) 

     for i, question in enumerate(extra): 
      self.fields['fieldname_%s' % i] = forms.CharField(label=question) 

    def extra_fields(self): 
     for name, value in self.cleaned_data.items(): 
      if name.startswith('fieldname_'): 
       yield (self.fields[name].label, value) 

И называть его с точки зрения:

def doSomething(request, extra_fields): 
    form = MyForm(request.POST or None, extra=extra_fields) 
    if form.is_valid(): 
     for (question, answer) in form.extra_answers(): 
      save_answer(request, question, answer) 
     return redirect("create_user_success") 

return render_to_response("template/form.html", {'form': form}) 

Очень аккуратными, поздравляю Джейкоб Каплан-Мосс

Смежные вопросы