问题
I am trying to edit existing objects using my Django FormWizard. I am following the technique described in this blog post, but it does not work. Here is my edit view:
@login_required
def edit_wizard(request, id):
thing = get_object_or_404(Thing, pk=id)
if thing.user != request.user:
raise HttpResponseForbidden()
else:
initial = {0: {'year': thing.year,
'make': thing.make,
'series': thing.series,
....etc.
},
1: {'condition': thing.condition,
....etc.
},
}
form = CreateWizard.as_view([StepOneForm, StepTwoForm, StepThreeForm], initial_dict=initial)
return form(context=RequestContext(request), request=request)
Can you help me figure out how to provide the initial data to the Wizard so that I can allow users to edit their objects? Thanks for your ideas!
EDIT: (2/18/13)
Was getting a:
TypeError at /edit/10/ __init__() takes exactly 1 argument (3 given)
This was solved by @sneawo's answer below, but still no initial data is passed, and the wizard instead creates new objects.
EDIT: (2/19/13)
class CreateWizard(SessionWizardView):
file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT))
def done(self, form_list, **kwargs):
instance = Thing()
for form in form_list:
for field, value in form.cleaned_data.iteritems():
setattr(instance, field, value)
instance.user = self.request.user
instance.save()
return render_to_response('wizard-done.html', {
'form_data': [form.cleaned_data for form in form_list],
})
回答1:
As per the documentation, for Django 1.4+ you pass the initial data in initial_dict keyword argument. For previous versions(1.3, it seems it wasn't there before 1.3) the keyword argument was initial. Also, the keys for steps in your initial data dict should be strings not integers.
initial = {'0': {'year': thing.year,
'make': thing.make,
'series': thing.series,
....etc.
},
'1': {'condition': thing.condition,
....etc.
},
}
UPDATE: To update the same object you have to set the id also, otherwise there is no way for django to know which object to update. A simple way to do it is to pass the id in a hidden field, but you have to do the user permission check again in your (done) method.
initial = {0: {'id': thing.id,
class CreateWizard(SessionWizardView):
file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT))
def done(self, form_list, **kwargs):
id = form_list[0].cleaned_data['id']
thing = get_object_or_404(Thing, pk=id)
if thing.user != self.request.user:
raise HttpResponseForbidden()
else:
instance = Thing()
for form in form_list:
for field, value in form.cleaned_data.iteritems():
setattr(instance, field, value)
instance.user = self.request.user
instance.save()
return render_to_response('wizard-done.html', {
'form_data': [form.cleaned_data for form in form_list],})
and of course StepOneForm should have id with hidden field:
class StepOneForm(forms.Form):
id = forms.IntegerField(widget=forms.HiddenInput)
回答2:
Try to use form = CreateWizard.as_view([StepOneForm, StepTwoForm, StepThreeForm], initial=initial)
来源:https://stackoverflow.com/questions/14942686/edit-django-formwizard-getting-initial-data