4

这个问题与之前在这里提出并回答的问题高度相关:如何将 FormWizard 包装在视图中?

有人可以发布他们如何成功地将 Django 表单向导包装到视图中的确切详细信息,以便可以使用 login_required 装饰器吗?互联网上有很多关于这个主题的讨论,但它们似乎都不完整,因为它们实际上并没有展示他们是如何定义表单向导类的。

当我将浏览器指向视图时,出现以下异常:

__init__() takes exactly 1 non-keyword argument (2 given) in views.py line #108

当我实例化我的表单向导对象时我传递了哪些参数,这样它就不会给我这个错误?如果您有一些有效的示例代码,请发布。

这是我的 urls.py 文件中的内容:

url(r'^createObject/$', views.createObjectView, name='createObject'),

这是我的 views.py 文件中的内容:

CREATE_OBJECT_FORMS = [
    ("createMyForm0", createObjectForm0),
    ("createMyForm1", createObjectForm1),
    ("createMyForm2", createObjectForm2),
    ("createMyForm3", createObjectForm3),
]

CREATE_OBJECT_TEMPLATES = {
    "createMyForm0": "myApp/form0.html",
    "createMyForm1": "myApp/form1.html",
    "createMyForm2": "myApp/form2.html",
    "createMyForm3": "myApp/form3.html",
}




@login_required
def createObjectView(request):
    # Set up the dictionary of initial data for the form
    # In this case, we are pre-filling some data from the first form only
    initial = {0: {}}

    # Create the form wizard
    form = createObjectWizard(
        [
            createObjectForm0,
            createObjectForm1,
            createObjectForm2,
            createObjectForm3,
        ], 
        initial=initial      # This is Line #108
    )

    # Call the form wizard passing through the context and the request
    return form(context=RequestContext(request), request=request)    




class createObjectWizard(SessionWizardView):
    def get_template_names(self):
        return [CREATE_OBJECT_TEMPLATES[self.steps.current]]

    def done(self, form_list, **kwargs):
        doSomethingFunction(form_list)
        return HttpResponseRedirect('/objectCreated/')
4

2 回答 2

13

as_view函数将基于类的视图转换为可调用视图:

我的应用程序/views.py

from django import forms
from django.contrib.auth.decorators import login_required
from django.contrib.formtools.wizard.views import SessionWizardView
from django.template.response import TemplateResponse

class Form1(forms.Form):
    a = forms.CharField()

class Form2(forms.Form):
    b = forms.CharField()

FORMS = [("step1", Form1),
         ("step2", Form2)]

TEMPLATES = {"step1": "wizard_step.html",
             "step2": "wizard_step.html"}

class MyWizard(SessionWizardView):

    def get_template_names(self):
        return [TEMPLATES[self.steps.current]]

    def done(self, form_list):
        # get data from forms
        a = self.get_cleaned_data_for_step('step1')['a']
        b = self.get_cleaned_data_for_step('step2')['b']
        # access the request as self.request
        request = self.request
        # (...)
        # return response
        return TemplateResponse(request, 'wizard_success.html', {
            'a': a,
            'b': a
        })

wizard_view = MyWizard.as_view(FORMS)

@require_login
def wrapped_wizard_view(request):
    return wizard_view(request)

myapp/templates/wizard_step.html

{% extends "base.html" %}
{% load i18n %}

{% block content %}

<form method="post">
{% include "formtools/wizard/wizard_form.html" %}
</form>

{% endblock %}

我的应用程序/urls.py

from django.conf.urls import patterns, url

urlpatterns = patterns('myapp.views',
    url(r'^wizard/$', 'wrapped_wizard_view'),
)
于 2013-01-29T19:37:16.670 回答
2

另一个答案 -如文档中所述,Wizardview您始终可以在类上使用装饰器,而不是包装您的视图

因此,您将执行以下导入:

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator

然后在class createObjectWizard(SessionWizardView)您内部添加以下内容:

 @method_decorator(login_required)
 def dispatch(self, *args, **kwargs):
     return super(createObjectWizard, self).dispatch(*args, **kwargs)

这样你就不必搞砸了urls.py——这一切都在视图中得到了处理。希望这可以帮助

于 2015-02-20T15:42:53.403 回答