Django: обновление объекта в формах с помощью пользовательского метода сохранения

Это продолжение этого вопроса, в котором я научился использовать метод save многошагового мастера форм, чтобы сохранять поля формы по-разному в разных формах. Благодаря помощи @Yuji Tomita я понял, как правильно сохранять формы. Однако на данный момент я не понимаю, как обновить экземпляр и сохранить изменения в объекте.

Я попытался следовать логике, которую узнал от @Yuji, но не смог должным образом обновить объект.

Вот где я:

class StepOneForm(forms.Form):
     ...
     def save(self, thing):
        for field, value in self.cleaned_data.items():
            setattr(thing, field, value)

class StepTwoForm(forms.Form):
     ...
     def save(self, thing):
        for field, value in self.cleaned_data.items():
            setattr(thing, field, value)

class StepThreeForm(forms.Form):
     ...
     def save(self, thing):
         thing.point = Point.objects.get_or_create(latitude=self.cleaned_data.get('latitude'), longitude=self.cleaned_data.get('longitude'))[0]
         for field, value in self.cleaned_data.items():
             setattr(thing, field, value)

Вот как я перезаписал метод done мастера для сохранения экземпляров:

class MyWizard(SessionWizardView):
    file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT))
    def done(self, form_list, **kwargs):
        id = form_list[0].cleaned_data['id']
        try:
            thing = Thing.objects.get(pk=id)
            instance = thing
        except:
            thing = None
            instance = None
        if thing and thing.user != self.request.user:
            raise HttpResponseForbidden()
        if not thing:
            instance = Thing()
            for form in form_list:
                form.save(instance)
            instance.user = self.request.user
            instance.save()
        return render_to_response('wizard-done.html', {
                'form_data': [form.cleaned_data for form in form_list],})

Как мне изменить метод save, чтобы правильно обновить экземпляр thing? Спасибо за ваши идеи!


РЕДАКТИРОВАТЬ: добавление представления, которое редактирует объект:

def edit_wizard(request, id):
    thing = get_object_or_404(Thing, pk=id)
    if thing.user != request.user:
        raise HttpResponseForbidden()
    else:
        initial = {'0': {'id': thing.id,
                       'year': thing.year,
                       'color': thing.color,
                       ... #listing form fields individually to populate the initial_dict for the instance
                       },
                   '1': {image': thing.main_image,
                       ...
                       },
                   '2': {description': thing.additional_description,
                       'latitude': thing.point.latitude,  #thing has a foreign key to point that records lat and lon
                       'longitude': thing.point.longitude,
                       },
                    }

        form = MyWizard.as_view([StepOneForm, StepTwoForm, StepThreeForm], initial_dict=initial)
        return form(context=RequestContext(request), request=request)

person Nick B    schedule 07.10.2013    source источник
comment
Вы запускаете instance.save() после всего этого?   -  person mariodev    schedule 08.10.2013
comment
Спасибо за ваш комментарий @mariodev. Я запускаю instance.save() в методе done моего мастера форм. Я включил эту информацию выше в редактирование. Спасибо за любые идеи, которые могут помочь мне разобраться в этой сложной проблеме!   -  person Nick B    schedule 08.10.2013


Ответы (1)


В чем проблема, которую вы видите? Получить ошибку или объект не сохраняется?

Вероятно, отступ в вашем методе done() неверен, поэтому он не вызывает метод form.save(). Это должно быть так:

class MyWizard(SessionWizardView):
    file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT))
    def done(self, form_list, **kwargs):
        ... 
        #existing code

        if not thing:
            instance = Thing()

        #this is moved out of if
        for form in form_list:
            form.save(instance)

        instance.user = self.request.user
        instance.save()
        return render_to_response('wizard-done.html', {
                'form_data': [form.cleaned_data for form in form_list],})
person Rohan    schedule 11.10.2013
comment
Вы правы, это была проблема. Я не знаю, почему, но мне пришлось изменить метод сохранения только в третьей форме на def save(self, thing): вместо def save(self, instance): Две другие формы, которые я использовал def save(self, instance): Есть идеи, почему? В любом случае большое спасибо! - person Nick B; 15.10.2013
comment
@NickB, если его форма модели, то у него будет атрибут instance, который может вызвать путаницу. Но не уверен, что это так. - person Rohan; 16.10.2013