我有一个用于用户反馈的表单视图:
urls.py:
url(
r'^feedback/$',
'tool.views.Feedback',
name='feedback'
),
url(
r'^thanks/$',
direct_to_template, {
'template': 'tool_feedback_thanks.html'
},
name='feedback_thanks'
),
forms.py:
class FeedbackForm(forms.Form):
yes_no = forms.ChoiceField(
choices=YES_NO_CHOICE,
initial=1,
widget=forms.RadioSelect(attrs={'class': 'can_reveal_input'}),
label="Are you happy with Our service?"
)
comments = forms.CharField(
widget=forms.Textarea(attrs={
'class': 'hidden', 'placeholder': 'Leave us your comments...'
}),
required=False,
label=""
)
views.py:
def Feedback(request,
template_name='tool_feedback.html'):
title = u'Leave us some feedback'
form = FeedbackForm(request.POST or None)
if form.is_valid():
yes_no = form.cleaned_data['yes_no']
comments = form.cleaned_data['comments']
sender = "A Unirac website user"
recipients = ['[email protected]']
send_mail(yes_no, comments, sender, recipients)
return HttpResponseRedirect(
reverse('feedback_thanks')
)
return render_to_response(template_name, {
'title': title,
'form': form,
}, RequestContext(request))
这很不错,但现在客户要求将此表单包含在每个页面上。我猜表单可以通过 JS 提交到适当的 URL,但是在每个页面上包含未绑定表单的最佳方法是什么?
我会创建一个上下文处理器,将表单包含在每个视图中。
编辑:
要让用户访问他/她之前浏览的 URL,您可以仅使用 URL。
# yourapp/context_processors.py
def feedback_form_context_processor(request):
return {
'feedback_form': FeedbackForm(),
'feedback_form_url': reverse("feed_app:form_process", args=(request.path))
}
这就是 urls.py 的样子:
urlpatterns = patterns('feed_app.views',
url(r'^process-feedback-form/(?P<next_url>\d+)', 'form_process', name='form_process'),
)
以及表单的视图:
def form_process(request, next_url):
# Process form, do your stuff here
# if its valid redirect to the url
return redirect(next_url)
您应该构建模板以具有正确的布局。例如,有一个基本模板:
# templates/base.html
<html>
<body>
..
{% block maincontent %}
{% endblock %}
..
{# The form!!! #}
<form action='{{feedback_form_url}}' method='POST'>
@csrftoken
{{ feedback_form.as_p }}
</form>
</body>
</html>
要创建简单的视图,只需使用正确的模板。
# templates/just_a_random_view.html
{% extends base.html %}
{% block maincontent %}
<h1>Content!</h1>
{% endblock %}
最后,将其包含在您的设置中:
# settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
"django.contrib.auth.context_processors.auth",
...
"yourapp.context_processors.feedback_form_context_processor"
)
我相信包含表单的最简单方法是使用 assignment_tag:
模板库中:
@register.assignment_tag
def feedback_form(format_string):
return FeedbackForm()
在模板中
{% feedback_form as form %}
{# display form... %}
{{ form.as_p }}
补充一下@bmihelac,他的回答对我来说非常有效。自 django 2.0 起,
assignment_tag
已被弃用,取而代之的是 simple_tag
。因此,您几乎可以通过将 assignment_tag
替换为 simple_tag
来完全遵循他的答案,如下所示:
from django import template
from .forms import FeedbackForm
register = template.Library()
@register.simple_tag
def feedback_form():
return FeedbackForm()
然后只需参考 https://docs.djangoproject.com/en/2.1/howto/custom-template-tags/#code-layout 了解如何将其导入模板中!