【问题标题】:Django adding a feedback form on every pageDjango 在每个页面上添加一个反馈表
【发布时间】:2013-01-15 17:45:08
【问题描述】:

我有一个用户反馈的表单视图:

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 = ['person@example.com']
        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,但是在每个页面上包含未绑定表单的最佳方法是什么?

任何帮助将不胜感激。

【问题讨论】:

    标签: django django-forms django-views


    【解决方案1】:

    我会创建一个上下文处理器,以在每个视图中包含表单。

    编辑:

    要让用户访问他/她之前浏览的 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"
    )
    

    【讨论】:

    • 这看起来很棒。那么,“just_a_random_template.html”应该是我用于不同表单的模板(即 tool_feedback.html)?
    • 不,这只是您需要编写的视图示例。 just_a_random_template.html 可能是 login.htmlprocess_purchase.html。这个想法是您在视图中使用的所有模板都从具有表单的 base.html 扩展。
    • 因此,我将来自上下文处理器的表单包含在我的base.html 中,并将表单定向到现有视图,并将页面 url 作为 GET 变量获取。这样我就可以验证并返回到同一页面。这行得通,但它看起来像一个合理的模式吗?
    • 我做了一些改变来帮助你。你在我的回答中有所有的逻辑。实施它应该没有问题。
    • 感谢您提供非常全面的回答!
    【解决方案2】:

    我相信包含表单的最简单方法是使用assignment_tag

    在模板库中:

    @register.assignment_tag
    def feedback_form(format_string):
        return FeedbackForm()
    

    在模板中

    {% feedback_form as form %}
    {# display form... %}
    {{ form.as_p }}
    

    【讨论】:

    • 好的——这看起来很有趣——你能详细说明一下我的用例吗?我应该在我的视图上使用装饰器吗?我可以将它包含在base.html 模板中吗?
    • 你不需要装饰器,你可以在你的base.html模板中使用它。只需在 base.html 中包含您的模板库。如果您使用 ajax 或其他 URL 处理表单处理,这是最简单的。
    【解决方案3】:

    补充@bmihelac,谁的回答对我来说非常有效。由于 django 2.0 assignment_tagdeprecated 支持 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 了解有关如何将其导入模板的信息!

    【讨论】:

      猜你喜欢
      • 2018-07-18
      • 2011-02-13
      • 2017-01-21
      • 2021-03-26
      • 2013-03-05
      • 1970-01-01
      • 2013-02-16
      • 2020-10-16
      • 2020-09-09
      相关资源
      最近更新 更多