4

この質問は、以前に尋ねられ、ここで回答されたものと非常に関連しています: How wrap a FormWizard in a View?

login_required デコレータを使用できるように、Django フォーム ウィザードをビューにラップする方法の正確な詳細を投稿できますか? このトピックについてはインターネット上で多数の議論がありますが、フォーム ウィザード クラスをどのように定義したかが実際には示されていないため、それらはすべて不完全なようです。

ブラウザをビューに向けて実行すると、次の例外が発生します。

__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関数は、クラス ベースのビューを呼び出し可能なビューに変換します。

myapp/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 %}

myapp/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 に答える