问题
I am trying to build a django form wizard to allow people to register for an
event. I can get through the form wizard and see data in the done
method.
The problem is that I also need event_id
passed into done also. How do I get
event_id
from the url through the form wizard and into done
? Simple example?
------- urls.py ---------
named_register_forms2 = (
('basicdata', SeatsForm),
('form2', AnotherForm),
)
urlpatterns = patterns('',
url(r'^register/(?P<event_id>\d+)/$', register_wizard, name='register_step'),
)
------ forms.py -----------
class SeatsForm(forms.ModelForm):
class Meta:
model = MyModel
fields = [ 'last_name', 'first_name', 'address1', 'address2',
'city', 'state', 'zipcode', 'phone_number', 'email']
def __init__(self, *args, **kwargs):
super(SeatsForm, self).__init__(*args, **kwargs)
class RegisterWizard(SessionWizardView):
#storage_name = 'formtools.wizard.storage.session.SessionStorage'
template_name = 'wizard_form.html'
def done(self, form_list, **kwargs):
data = {}
for form in form_list:
data.update(form.cleaned_data)
print data
# I need event_id right here. How to get it?
return render_to_response('done.html', {
'form_data': [form.cleaned_data for form in form_list],
})
回答1:
I think you will have to put that in the form and get it from there.
If its model form you can pass instance_dict
param to the wizard view. instance_dict param. However in that case you will have to implement a wrapper view that will prepare the wizard view with these params. Something like this:
def wrapper_view(request, id):
#somecode
seats_instance = SeatsModel.objects.get(id=id)
another_instance = AnotherModel.objects.get(id=id)
inst_dict = { '0': seats_instance,
'1': another_instance
}
return RegisterWizard.as_view(named_register_forms2, instance_dict=inst_dict)(request)
class RegisterWizard(SessionWizardView):
#storage_name = 'formtools.wizard.storage.session.SessionStorage'
template_name = 'wizard_form.html'
def done(self, form_list, **kwargs):
data = {}
seatform= form_list[0]
seatinst = form.save()
#save other forms
...
#using seatinst get event id
return render_to_response('done.html', {
'form_data': [form.cleaned_data for form in form_list],
})
回答2:
The question is two years old, but for completeness, I've been solving this problem by overriding the dispatch
method of the wizard class. This method is called by the wizard with the raw arguments from the URL dispatcher. You can modify the wizard's instance_dict
(and presumably any other wizard member) before anything else happens.
class RegisterWizard(SessionWizardView):
#storage_name = 'formtools.wizard.storage.session.SessionStorage'
template_name = 'wizard_form.html'
def dispatch(self, request, id, *args, **kwargs):
self.instance_dict = {
'0': SeatsModel.objects.get(id=id),
'1': AnotherModel.objects.get(id=id),
}
return super(RegisterWizard, self).dispatch(request, *args, **kwargs)
def done(self, form_list, **kwargs):
data = {}
seatform= form_list[0]
seatinst = form.save()
#save other forms
...
#using seatinst get event id
return render_to_response('done.html', {
'form_data': [form.cleaned_data for form in form_list],
})
I'm not sure there is any major functional advantage, but it feels like the wizard is a little more encapsulated doing it this way. In addition I've no idea if this was the intended use of the dispatch
method.
I suppose if one were to inherit RegisterWizard
the behaviour of setting instance_dict
with objects from SeatsModel
and AnotherModel
would be available without the need to make user of a wrapper function; that might be the only actual advantage of doing it this way.
来源:https://stackoverflow.com/questions/11840544/passing-data-through-a-django-formwizard