如何在 django-cms 中使用表单?

Posted

技术标签:

【中文标题】如何在 django-cms 中使用表单?【英文标题】:how to use forms in django-cms? 【发布时间】:2011-07-23 12:34:18 【问题描述】:

我是 django-cms 的绝对新手。我已经完成了本教程,并按照文档中的说明对其进行了配置。现在,我必须构建一个使用表单上传产品的应用程序。

我不知道如何继续前进。我想以简单的形式开始它,就像现在,比如用户名和密码文本框。如何在 django-cms 页面中使用 django 表单?我也启用了 sn-p 插件。我需要一些指导。

请有任何建议。 谢谢

【问题讨论】:

确实似乎没有合理的方法来做到这一点,这将支持在表单中显示错误并使用简单的 Django 表单,因为它们在其他地方使用。 【参考方案1】:

假设您的产品应用程序按预期工作没有 Django CMS,您接下来要做的是创建自己的插件来显示表单。该插件将呈现您已经使用您创建的插件模板在您自己的应用程序中定义的表单。

此联系表单插件允许将联系表单插入页面模板中占位符允许的任何位置。

class ContactPlugin(CMSPluginBase):
    """Enables latest event to be rendered in CMS"""

    model = CMSPlugin
    name = "Form: Contact"
    render_template = "contact_form/contact_plugin.html"

    def render(self, context, instance, placeholder):
        request = context['request']
        context.update(
            'instance': instance,
            'placeholder': placeholder,
            'form': ContactForm(request=request),
        )
        return context

模板将包含呈现表单所需的所有 HTML 和 Django 模板语言。

这个其他联系表单插件展示了另一个如何做到这一点的例子。它只是更新上下文,而不是呈现表单。好处是您不必创建单独的模板,但坏处是您失去了拥有插件的一些模块化。这取决于呈现表单的页面模板。

class ContactPlugin(CMSPluginBase):
    model = Contact
    name = _("Contact Form")
    render_template = "contact.html"

    def render(self, context, instance, placeholder):
        request = context['request']

         if request.method == "POST":
            form = ContactForm(request.POST)
            if form.is_valid():
                form.send(instance.site_email)
                context.update( 
                    'contact': instance,
                    )
            return context
        else:
            form = ContactForm()

            context.update(
            'contact': instance,
            'form': form,
            )
            return context

在任何一种情况下,您仍然必须定义视图以接受表单提交,这意味着您需要在 CMS 之外创建一个视图,以确认收到带有自己模板的表单,将用户重定向回引用页面,和/或接受 AJAX 请求。

【讨论】:

好的,我明白你的意思了。但是如果我创建一个插件,它的名字应该是什么?我应该把它保存在哪里? 您可以随意命名插件。你应该做的是在一个恰当命名的文件中创建插件在你自己的应用程序中,然后用 Django CMS 注册你的插件。我强烈建议参考custom plugin documentation 来了解如何创建一个基本插件,以及一些example extensions 的来源。一旦你有你的数据处理视图(在你的应用程序中),表单插件只是在模板中呈现表单。 仍然,发布到其他视图,您如何向用户显示错误? 如果您引用 ojii 的答案(这是解决此问题的方法),您可以通过以下两种方式之一显示错误:呈现单独的表单视图(在处理表单请求的 URL 端点)或通过 AJAX 做同样的事情。后者将提供更好的用户体验。 我创建了一个插件来处理这一切,因为我遇到了类似的问题,请参阅我的回答或github.com/metzlar/cms-form-plugin【参考方案2】:

实际上,bennylope 提出的the solution 并不是首选的方法,因为在插件中使用 request.POST 可能会产生非常糟糕的副作用(例如:如果同一个插件在一个页面上出现两次怎么办?或者如果有多个插件在同一页面上等待 POST 数据?当该页面有 POST 时,这些插件会相互混淆)。

所以首选的方式是:

由 bennylope 创建一个 CMSPlugin as described 以渲染表单。 将表单发布到静态挂钩视图(或应用挂钩视图),如果 POST 成功,请根据需要再次重定向到页面。

【讨论】:

正如我所说,我绝对是 django-cms 的新手。我可以看一个 cms 插件的 sn-p,以便更好地理解吗? 即使在同一页面上多次使用下面的插件,表单也不会提交到 CMS 页面本身,而是提交到单独的视图(如我回复的最后一句所述) .在下面的两个示例中,每个表单都与发送数据的位置无关;这是在插件模板中声明的。 bennylope,那你为什么会有if request.method == 'POST' 呢? 哎呀,我真的错过了。从an extension featured in the Django CMS extensions gallery 复制该示例。在您的评论中考虑我的第一个示例。 如果表单没有验证怎么办?正如 lentschi 在下面指出的那样,这是不可接受的。【参考方案3】:

我也是 django-cms 的新手,但 ojii 描述 in their answer 的方式似乎是最合理的:

制作一个如上所述的 CMSPlugin 来呈现表单。 将表单发布到静态挂钩视图(或应用挂钩视图),如果 POST 成功,请根据需要再次重定向到页面。

但是对我来说这只是一个部分解决方案,因为我不仅想在成功的情况下重定向回包含插件的 cms 页面,而且在需要显示表单错误的情况下。重定向部分不是问题(我只是重定向回 request.META["HTTP_REFERER"]),但是将表单(错误)移交给包含插件的 cms 页面的部分很棘手。 我为此找到的唯一答案:我使用会话(将表单写入静态视图中的会话,然后在插件的渲染方法中再次删除它)。不是最好的方法,但它有效。 (会有更好的方法,如果 cms 插件配置支持某种方式来重定向而不是渲染,但显然没有这样的选项:见http://groups.google.com/group/django-cms/browse_thread/thread/79ab6080c80bbcb5)

【讨论】:

【参考方案4】:

您可以通过抛出异常并在中间件中捕获它来解决问题: http://djangosnippets.org/snippets/2541/

【讨论】:

这个看起来很不错也很简单:github.com/jonasgeiregat/django-excepted【参考方案5】:

我最近遇到了django-form-designer

它非常好,可以让您以所见即所得的方式设计表单。适用于独立的 django 应用程序,并有一个用于 Django-CMS 的附加插件。注意:除了 Django-CMS 安装说明外,您还必须遵循独立说明。

来自github描述:

主要特点:

从 Django 管理员设计联系表单、搜索表单等,无需编写任何代码 可以记录表单数据并以 CSV 格式导出、通过电子邮件发送或转发到任何网址 与 Django CMS 集成:向任何页面添加表单 使用拖放功能更改表单域的位置 完全可折叠的管理界面可更好地概览您的表单 实现了 Django 中包含的许多表单字段(TextField、EmailField、DateField 等) Django 提供的验证规则是完全可配置的(最大长度、正则表达式等) 可自定义的消息和标签 支持 POST 和 GET 表单

【讨论】:

【参考方案6】:

这可能为时已晚,但我遇到了类似的问题,所以我创建了一个更通用的插件:https://github.com/metzlar/cms-form-plugin,它恰好与 bennylope 的答案非常相似。

【讨论】:

以上是关于如何在 django-cms 中使用表单?的主要内容,如果未能解决你的问题,请参考以下文章

如何转储 django-cms 相关内容以便与正在运行的实例一起迁移?

django-cms 和 jQuery

如何将 nginx 位置添加回 302 重定向响应位置

django django-cms 我没有成功访问应用程序的 urls.py

Django-cms 和自动阻塞

在不同的占位符/模板上以不同的方式呈现 Django-CMS 插件