Django表单中灵活数量的表单字段

时间:2014-06-27 15:41:51

标签: django python-2.7 django-forms django-templates formsets

我想创建一个包含多个字段的表单

class MainForm(forms.Form):
    name = forms.CharField(label='name')
    comment = forms.CharField(label='comment')

现在我们有一个字段"评论"。现在我希望用户可以通过网站向表单添加更多注释字段。

所以我需要:

1)更灵活地定义表单,以便可以有N个注释字段。 (默认值为N = 1)

2)定义添加新注释字段的方法。

3)定义实用程序功能,例如清理表单字段,这些功能非常灵活,可以处理动态数量的注释字段。

我想了解如何以干净的方式进行设置。

2 个答案:

答案 0 :(得分:1)

Formsets是一个很好的解决方案:

https://docs.djangoproject.com/en/1.6/topics/forms/formsets/

它会干净地处理1和3。我必须在过去编写javascript,以便在单击add时在表单中注入额外的字段。然后提交django照顾其余部分。

答案 1 :(得分:0)

所以我找到了适合我的东西,我想至少发布我所做的粗略草稿。

首先,我确实发现%20的建议使用django formsets非常有帮助。我的forms.py看起来大致如下:

from django import forms
from django.forms.formsets import formset_factory
from django.forms.forms import NON_FIELD_ERRORS

class CommentForm(forms.Form):
    comment = forms.CharField(label='comment')

class MainForm(forms.Form):
    name = forms.CharField(label='name')

    def __init__(self):
        self.commentFormset =  formset_factory(CommentForm, extra=1)
        self.comments = self.commentFormset()

    def clean(self):
        cleaned_data = super(MainForm, self).clean()

        for nForm, commentForm in enumerate(self.comments):
            if commentForm.is_valid():
                pass
            else:
                self._errors[NON_FIELD_ERRORS] = self.error_class(['Invalid Comments'])

以下是我的views.py

的相关部分
from forms import MainForm

def commentView(request):
    if request.method == 'POST':
        form = MainForm(data=request.POST)
        form.comments = form.commentFormset(data=request.POST)

    if form.is_valid():
        # ...
        for commentForm in form.comments:
            if commentForm.is_valid():
                # do some stuff with each comment
    else:
        form = MainForm()

    template = loader.get_template('main.html')
    context = RequestContext(request, { 'form': form })

    return HttpResponse(template.render(context))

我找到了以下精彩的jquery插件:http://blog.stanisla.us/2009/10/10/jquery-plugin-django-dynamic-formset/ 这使我能够为用户提供添加和删除注释字段的机会。 view.py或forms.py中不需要额外的代码。

以下是我模板中的相关摘录。

<script type="text/javascript" src="{{ STATIC_URL }}jquery.formset.js"></script>
<script type="text/javascript">
$(function() {
        $('tr.comment-form').formset( { prefix: 'form' });
    })
</script>

 <div id="commentSection">
    Comments:
    <table>
        <tbody>
          {{ form.comments.management_form }}
          <th>Comment</th><th></th>
          {% for commentForm in form.comments %}
          <tr class="comment-form">
            <td>{{ commentForm.comment.errors }}{{ commentForm.comment }}</td>
            <td></td>
          </tr>
          {% endfor %}
        </tbody>
      </table>
  </div>