Пример динамической формы Django - PullRequest
10 голосов
/ 27 мая 2011

У меня есть простое требование для создания динамической формы в Django - я видел много примеров, но они кажутся неполными или требуют более глубоких знаний Python и Django, чем у меня! Ни один из них не показывает, как должна называться динамическая часть примера:

Это класс формы с Q1 и Q2 - я помещаю кнопку в форму, чтобы добавить другой поле с именем Q3 - и затем Q4 при повторном нажатии: я думаю, что я получил init полуправильную функцию:

class testform(forms.Form):
    Q1 = forms.CharField()
    Q2 = forms.CharField()

    def __init__(self, *args, **kwargs):
        super(testform,self).__init__(*args,**kwargs)
        self.fields['Q%s'%i] = forms.CharField(label='Q%i' % i)

Я хочу разместить кнопку на форме, чтобы добавить другую поле называется Q3, а затем Q4 при повторном нажатии.

  • Как мне вызвать функцию _ init _ из представления, чтобы добавить эти поля?
  • Если я использую Javascript для динамического добавления поля, как мне вызвать init , чтобы я мог правильно проверить с помощью Django при отправке формы?

Ответы [ 2 ]

9 голосов
/ 27 мая 2011

Чтобы ответить на ваш вопрос: всякий раз, когда вы инициализируете форму, она вызывает init (). Пример: form = testform(). Это инициализирует вашу форму. То, что я хотел бы сделать здесь, это добавить некоторый JavaScript для создания этих новых полей. Я не уверен, насколько вы знакомы с javascript, но я собираюсь предположить, что вы можете понять это самостоятельно.

Что касается проверки, это можно сделать в форме. Однако сначала вы захотите сообщить, что добавили больше полей, используя <strong>init</strong>().

class TestCharField(forms.CharField):
    def __init__(self, *args, **kwargs):
        super(TestCharField, self).__init__(*args, **kwargs) # Needs * and **
    def clean(self, value):
        super(TestCharField, self).clean(value)
        # Do custom validation in here
        return value

class testform(forms.Form):
    def __init__(self, *args, **kwargs):
        super(testform, self).__init__(args, kwargs)

        # args should be a list with the single QueryDict (GET or POST dict)
        # that you passed it
        for k,v in args[0].items():
            if k.startswith('Q') and k not in self.fields.keys():
                self.fields[k] = TestCharField(initial=v, required=True)

Вы можете назвать свое поле как угодно, оно не обязательно должно быть TestCharField. Просто не забудьте переименовать его в обоих местах. Это позволит вам заполнить столько полей, сколько захотите. Дайте мне знать, если это не сработает для вас.

0 голосов
/ 27 мая 2011

[Редактировать] Это был не лучший ответ, ответ Брайса намного лучше.Я взял вопрос буквально и дал решение для 4 полей, где действительно динамичная форма была бы гораздо более элегантным решением.

Пожалуйста, посмотрите на ответ Брайса.


Я думаю, я бы определил форму со всеми возможными полями и скрыл / показал бы ее с помощью javascript:

class testform(forms.Form)
    Q1 = forms.CharField()
    Q2 = forms.CharField()
    Q3 = forms.CharField()
    Q4 = forms.CharField()

HTML:

<table>
  {{ testform.as_table }}
</table>
...
<script type="text/javascript">
    $(function(){
        $('input[name="q3"]').closest('tr').hide();
        $('input[name="q4"]').closest('tr').hide();
    });
</script>

(с использованием JQuery)
И аналогичным образом показывайте поля с помощью кнопок.

...