无法在一个模板中输出多个表单

时间:2013-09-14 01:45:17

标签: django django-forms django-templates django-views

我有一个包含多个可编辑和不可编辑组件的用户设置页面。每个可编辑组件都有自己的形式。所有组件都显示在表格中,内容来自模型上的字典。例如:

class MyUser(models.AbstractBaseUser):

    def get_settings(self):
        return [
            ('Email Address',
                {'value': self.email, 'editable': True, 'section': 'email', 'form': 'email_form'}
            ), 
            ('Password', 
                {'value': '', 'editable': True, 'section': 'password', 'form': 'password_form'})]

然后我为设置中的每个项目定义了一个表单,例如:

class ChangeEmailForm(models.ModelForm):

    class Meta:
        fields = ['email']
        model = models.MyUser

    email = forms.EmailField(widget = forms.TextInput(attrs={'placeholder': 'Email Address'}))

所有表单都由一个视图处理,在该视图中,它们被分配了一个名称,该名称与模型中设置数据中的名称相匹配:

def edit_settings_view(request, user):
    if request.POST:
        if 'email_form' in request.POST:
        if email_form.is_valid():
            email_form.save()
            return HttpResponseRedirect('/settings/')
        else:
            form_errors = email_form.errors
            return render(request, 'settings.html', {'my_user'=user, 'email_form'=email_form, 'form_errors'=form_errors})
    else:
        email_form = ChangeEmailForm(instance=user)
    return render(request, 'settings.html', {'my_user'=user, 'email_form'=email_form})

尝试在模板中渲染表单时出现问题。我目前有:

{% for key, value in my_user.get_settings %}
    <form action="{% url "edit_profile" %}" method="post">
        {% csrf_token %}
        <p>
            {% for field in value.form %}
                {{ field }}
            {% endfor %}
        <button type="submit" name=value.form>Save</button>
    </p>
</form>

然而,这只是打印表单的名称,例如'email_form'。我理解为什么会这样,但我不知道如何让模板显示表单。此外,还有更好的方法来处理用户设置吗?我在这里展示的代码非常简洁,但它基本上针对每个不同的设置重复,这不是很干燥

1 个答案:

答案 0 :(得分:0)

我通过以下方式解决了我的问题。

首先,我将所有表单传递给字典中的模板,如下所示:

forms = {'email_form': email_form, 'password_form': password_form}
return render(request, 'settings.html', {'my_user'=user, 'forms'=forms})

然后我从其字符串名称中获取了带有自定义标记的表单:

@register.assignment_tag(name='get_form', takes_context=True)
def get_form(context, form_name):
    forms = context['forms']
    form = forms[form_name]
    return form

显然,如果我没有改变传递表单的方式,那么标签就可以与form = context[form_name]一起使用,所以这个答案的重要部分就是标签。

我仍然认为我的代码可以减少重复次数,但至少现在可以使用了!