how to use forms in django-cms?

2019-03-24 18:52发布

I am an absolute novice to django-cms. I have gone through the tutorial and configured it exactly the same as mentioned in the documentation. Now, I have to build an application which uses a form to upload products.

I dont have a clue as to how to move ahead with it. I want to start it with simple forms as if now, say, a username and password textbox kind of. How can I use django forms in the django-cms page? I have snippet plugin enabled in it too. I need some guidance for this.

Any suggestions plsss. thanks

6条回答
啃猪蹄的小仙女
2楼-- · 2019-03-24 19:27

This might be way too late but I had a similar problem so I created a more general plugin: https://github.com/metzlar/cms-form-plugin which happens to be very similar to bennylope's answer.

查看更多
欢心
3楼-- · 2019-03-24 19:32

Assuming your product application works as expected without Django CMS, what you'd next want to do is create your own plugin to show the form. The plugin would render your form, which you've already defined in your own application using a plugin template that you've created.

This plugin for a contact form allows the contact form to be inserted into the page template anywhere a placeholder will allow it.

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

The template would include all the HTML and Django template language necessary to render the form.

This other contact form plugin shows another example of how to do it. Instead of rendering the form it just updates the context. The upside is that you don't have to create a separate template, but the downside is that you lose some of the modularity of having a plugin. This depends on the page template rendering the form.

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

In either case you still have to define the view to accept the form submission, which means you'll need to create a view outside of the CMS acknowledging receipt of the form with its own template, redirecting the user back to the referring page, and/or accepting an AJAX request.

查看更多
Anthone
4楼-- · 2019-03-24 19:33

I'm new to django-cms too, but the way ojii described seems like the most reasonable:

  • Make a CMSPlugin as described above to render the form.
  • Make the form post to a statically hooked view (or a apphooked view), if the POST is successful, redirect to the page again if you want.

However for me this only a partial solution because I don't only want to redirect back to the cms page containing the plugin in the case of success but also in the case of form errors which need to be displayed. The redirecting part is not the problem (I just redirect back to request.META["HTTP_REFERER"]), but the part of handing over the form (errors) to the cms page containing the plugin is tricky. The only answer I found for this: I use a session (Writing the form into the session in the static view, and then deleting it again in the plugin's render method). Not the nicest way, but it works. (There would be better ways, if the cms plugins configuration would support some way to redirect instead of rendering, but apparently there is no such option: see http://groups.google.com/group/django-cms/browse_thread/thread/79ab6080c80bbcb5 )

查看更多
趁早两清
5楼-- · 2019-03-24 19:36

Actually the solution proposed by bennylope is not the preferred way to do it, since using request.POST in a plugin can have very bad side effects (eg: what if the same plugin is twice on a page? Or what if there's multiple plugins waiting for POST data on the same page? Those plugins would confuse each other when there's a POST to that page).

So the preferred way is:

  • Make a CMSPlugin as described by bennylope to render the form.
  • Make the form post to a statically hooked view (or a apphooked view), if the POST is successful, redirect to the page again if you want.
查看更多
Explosion°爆炸
6楼-- · 2019-03-24 19:38

You can work around by throwing an exception and catching it in middleware: http://djangosnippets.org/snippets/2541/

查看更多
Ridiculous、
7楼-- · 2019-03-24 19:44

I've recently ran across django-form-designer

It's quite nice and lets you design forms in a wysiwyg manner. Works for stand alone django applications and has an additional plugin for Django-CMS. One note: you have to follow the standalone instructions in addition to the Django-CMS instructions for installation.

From the github description:

Key features:

  • Design contact forms, search forms etc from the Django admin, without writing any code
  • Form data can be logged and CSV-exported, sent via e-mail, or forwarded to any web address
  • Integration with Django CMS: Add forms to any page
  • Use drag & drop to change the position of your form fields
  • Fully collapsible admin interface for better overview over your form
  • Implements many form fields included with Django (TextField, EmailField, DateField etc)
  • Validation rules as supplied by Django are fully configurable (maximum length, regular expression etc)
  • Customizable messages and labels
  • Supports POST and GET forms
查看更多
登录 后发表回答