Django FormWizard as_view() method AttributeError

2019-07-31 06:44发布

问题:

I want to incorporate a FormWizard to handle a long form. After researching, it seems that django-merlin is the best option since it manages the formwizard via sessions. Trying to incorporate it (as mentioned in the django wizard docs), however, results in an AttributeError: type object 'CreateWizard' has no attribute 'as_view'.

Here is what it looks like:

from merlin.wizards.session import SessionWizard

class StepOneForm(forms.Form):
    year = forms.ChoiceField(choices=YEAR_CHOICES)
    ...

class StepTwoForm(forms.Form):
    main_image = forms.ImageField()
    ...

class StepThreeForm(forms.Form):
    condition = forms.ChoiceField(choices=CONDITION)
    ...

class CreateWizard(SessionWizard):
    def done(self, form_list, **kwargs):
        return HttpResponseRedirect(reverse('wizard-done'))

url:

url(r'^wizard/(?P<slug>[A-Za-z0-9_-]+)/$', CreateWizard.as_view([StepOneForm, StepTwoForm, StepThreeForm])),

Since the merlin docs are a little sparse, I chose to use the as_view() method as described in the original django form wizard docs, but it results in an AttributeError. How should I incorporate the merlin wizard in my urlconf? Thanks for your ideas!


This is the error and traceback that I get after updating based on @mVChr's answer and defining steps like this:

step_one = Step('step_one', StepOneForm())

Error and Traceback:

TypeError at / issubclass() arg 1 must be a class

Traceback:
File /lib/python2.7/django/core/handlers/base.py" in get_response
  89.                     response = middleware_method(request)
File "/lib/python2.7/django/utils/importlib.py" in import_module
  35.     __import__(name)
File "/myproject/myproject/urls.py" in <module>
  7. from myapp.forms import step_one, step_two, step_three, CreateWizard
File "/myproject/myapp/forms.py" in <module>
  16. step_one = Step('step_one', StepOneForm())
File "/lib/python2.7/merlin/wizards/utils.py" in __init__
  36.         if not issubclass(form, (forms.Form, forms.ModelForm,)):

Exception Type: TypeError at /
Exception Value: issubclass() arg 1 must be a class

Although Im still getting an error, I feel closer to the solution thanks to @mVChr. Any ideas on how to solve this error are greatly appreciated! Thanks for any ideas!

回答1:

Note: I do not know if this will work, I am just trying to help Nick B translate the docs with a specific example to get him closer to the proper solution. Please let me know if this works as-is and I will remove this comment.

From reading the docs it looks like you need to pass a list of Step objects directly to your SessionWizard subclass instantiation, as follows:

from merlin.wizards.session import SessionWizard
from merlin.wizards.utils import Step

class StepOneForm(forms.Form):
    year = forms.ChoiceField(choices=YEAR_CHOICES)
    ...
step_one = Step('step-one', StepOneForm())

class StepTwoForm(forms.Form):
    main_image = forms.ImageField()
    ...
step_two = Step('step-two', StepTwoForm())

class StepThreeForm(forms.Form):
    condition = forms.ChoiceField(choices=CONDITION)
    ...
step_three = Step('step-three', StepThreeForm())

class CreateWizard(SessionWizard):
    def done(self, form_list, **kwargs):
        return HttpResponseRedirect(reverse('wizard-done'))

And then in your urls.py:

url(r'^wizard/(?P<slug>[A-Za-z0-9_-]+)/$',
    CreateWizard([step_one, step_two, step_three]))


回答2:

Want to draw your attention that you use wrong syntax while making an object of Step. This

step_one = Step('step-one', StepOneForm())

should be like

step_one = Step('step-one', StepOneForm)

You have to correct it in all step object.