Исходные данные мастера форм для редактирования не загружаются должным образом в Django?

У меня есть трехстраничный список форм, выходящий из одной модели. Я мог сохранить модель в первый раз, но когда я хочу отредактировать модель, только первая форма показывает начальное значение, последующие формы не показывают начальные данные. но когда я печатаю initial_dict из представлений, я могу правильно видеть все начальные представления. Я следил за этим блог в мастере форм.

Вот мой model.py:

class Item(models.Model):
    user=models.ForeignKey(User)
    price=models.DecimalField(max_digits=8,decimal_places=2)
    image=models.ImageField(upload_to="assets/", blank=True)
    description=models.TextField(blank=True)

    def __unicode__(self):
        return '%s-%s' %(self.user.username, self.price)

URL.py:

urlpatterns = patterns('',

url(r'^create/$', MyWizard.as_view([FirstForm, SecondForm, ThirdForm]), name='wizards'),
url(r'^edit/(?P<id>\d+)/$', 'formwizard.views.edit_wizard', name='edit_wizard'),
)

формы.ру:

class FirstForm(forms.Form):
    id = forms.IntegerField(widget=forms.HiddenInput, required=False)
    price = forms.DecimalField(max_digits=8, decimal_places=2)
    #add all the fields that you want to include in the form

class SecondForm(forms.Form):
    image = forms.ImageField(required=False)

class ThirdForm(forms.Form):
    description = forms.CharField(widget=forms.Textarea)

просмотров.py:

class MyWizard(SessionWizardView):
    template_name = "wizard_form.html"
    file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT))
    #if you are uploading files you need to set FileSystemStorage
    def done(self, form_list, **kwargs):
        for form in form_list:
           print form.initial
        if not self.request.user.is_authenticated():
                raise Http404
        id = form_list[0].cleaned_data['id']
        try:
                item = Item.objects.get(pk=id)
                ######################   SAVING ITEM   #######################
                item.save()
                print item
                instance = item
        except:
                item = None
                instance = None
        if item and item.user != self.request.user:
                print "about to raise 404"
                raise Http404
        if not item:
                instance = Item()
                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], })


    def edit_wizard(request, id):
        #get the object
        item = get_object_or_404(Item, pk=id)
        #make sure the item belongs to the user
        if item.user != request.user:
            raise HttpResponseForbidden()
        else:
            #get the initial data to include in the form
            initial = {'0': {'id': item.id,
                             'price': item.price,
                             #make sure you list every field from your form definition here to include it later in the initial_dict
            },
                       '1': {'image': item.image,
                       },
                       '2': {'description': item.description,
                       },
            }
            print initial
            form = MyWizard.as_view([FirstForm, SecondForm, ThirdForm], initial_dict=initial)
            return form(context=RequestContext(request), request=request)

шаблон:

<html>
<body>
<h2>Contact Us</h2>
  <p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
  {% for field in form %}
    {{field.error}}
  {% endfor %}

  <form action={% url 'wizards' %} method="post" enctype="multipart/form-data">{% csrf_token %}
  <table>
  {{ wizard.management_form }}
  {% if wizard.form.forms %}
      {{ wizard.form.management_form }}
      {% for form in wizard.form.forms %}
          {{ form }}
      {% endfor %}
  {% else %}
      {{ wizard.form }}
  {% endif %}
  </table>
  {% if wizard.steps.prev %}
  <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">"first step"</button>
  <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">"prev step"</button>
  {% endif %}


  <input type="submit" value="Submit" />

  </form>

</body>
</html>

РЕДАКТИРОВАТЬ: я заметил следующее: в режиме редактирования, т. е. когда я нахожусь по следующему URL-адресу: http://127.0.0.1:8000/wizard/edit/1/, он правильно отображает данные первой формы, и когда я нажимаю «Отправить», он не переводит меня на шаг-2 режима редактирования, т.е. URL изменится на http://127.0.0.1:8000/wizard/create/.

Если после нажатия submit на URL-адресе редактирования (например, /wizard/edit/1) на первом этапе сохраняется тот же URL-адрес, то форма получит свои исходные данные на следующем этапе. но я не могу понять, как избежать изменения URL-адреса на /wizard/create


person brain storm    schedule 11.06.2014    source источник
comment
Одна проблема, которую я вижу, заключается в том, что вам не нужно передавать RequestContext() вызову представления мастера, поэтому попробуйте удалить это.   -  person Rohan    schedule 12.06.2014
comment
@Rohan Я пытался удалить RequestContext(), но это не помогло   -  person brain storm    schedule 13.06.2014
comment
@Rohan: я добавил дополнительную информацию в редактирование. Я надеюсь, что вы можете помочь. Спасибо   -  person brain storm    schedule 14.06.2014


Ответы (1)


Ошибка выглядит тривиальной. В вашем шаблоне действие формы имеет URL-адрес wizards, который является URL-адресом представления create. Следовательно, когда форма отправляется, она переходит к /wizard/create.

Чтобы использовать шаблон для обоих представлений, вы можете удалить атрибут action из тега form. Форма будет отправлена ​​на текущий URL-адрес, который можно создать или отредактировать.

Поэтому измените свой шаблон, чтобы иметь тег form как

<form method="post" enctype="multipart/form-data">

РЕДАКТИРОВАТЬ: чтобы сохранить элемент

Обновите свой вид как:

def done(self, form_list, **kwargs):
        for form in form_list:
           print form.initial
        if not self.request.user.is_authenticated():
                raise Http404
        id = form_list[0].cleaned_data['id']
        try:
                item = Item.objects.get(pk=id)
                print item
                instance = item
        except:
                item = None
                instance = None
        if item and item.user != self.request.user:
                print "about to raise 404"
                raise Http404
        if not item:
                instance = Item()

        #moved for out of if
        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], })
person Rohan    schedule 14.06.2014
comment
Спасибо, это помогло. но в режиме редактирования модель не перезаписывается. То есть изменения не сохраняются. можешь помочь что не так? - person brain storm; 15.06.2014
comment
@brainstorm, на ваш взгляд, если вы получаете item, вы на самом деле не используете его для сохранения. - person Rohan; 15.06.2014
comment
Спасибо за комментарий, я вставил item.save() в done method сейчас (вы можете видеть в коде выше). но это не спасло редактирование модели. Как вы думаете, мне следует сохранить item где-нибудь еще? - person brain storm; 15.06.2014
comment
: работал как шарм. Спасибо большое. Вы могли бы помочь мне с этим сообщением: вы уже прокомментировали это сообщение. но я вижу две копии загружаемых изображений (одну в fileStorage и одну в путь загрузки). как этого избежать? stackoverflow.com/questions/24176068/ - person brain storm; 15.06.2014