我有一个包含多个可编辑和不可编辑组件的用户设置页面。每个可编辑组件都有自己的形式。所有组件都显示在表格中,内容来自模型上的字典。例如:
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'。我理解为什么会这样,但我不知道如何让模板显示表单。此外,还有更好的方法来处理用户设置吗?我在这里展示的代码非常简洁,但它基本上针对每个不同的设置重复,这不是很干燥
答案 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]
一起使用,所以这个答案的重要部分就是标签。
我仍然认为我的代码可以减少重复次数,但至少现在可以使用了!