用于编辑的表单向导初始数据未在 Django 中正确加载? [英] form wizard initial data for edit not loading properly in Django?

查看:17
本文介绍了用于编辑的表单向导初始数据未在 Django 中正确加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个来自单个模型的三页表单列表.我第一次可以保存模型,但是当我想编辑模型时,只有第一个表格显示初始值,后续表格不显示初始数据.但是当我从视图打印 initial_dict 时,我可以正确地看到所有初始视图.我在表单向导上关注了这个博客.

I have a three page form-list coming out of a single model. I could save the model first time, but when I want to edit the model, only the first form shows the initial value, subsequent forms does not show the initial data. but when I print the initial_dict from views, I can see all the initial views correctly. I followed this blog on form wizard.

这是我的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)

urls.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'),
)

forms.py:

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)

views.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>

我注意到的一个是:在编辑模式下,即当我在以下网址时:http://127.0.0.1:8000/wizard/edit/1/,它正确显示第一个表单数据,当我单击提交时,它不会将我带到编辑模式的第 2 步,即 URL 更改为 http://127.0.0.1:8000/wizard/create/.

one this I noticed is the following: On the edit mode, i.e, when I am at the following url : http://127.0.0.1:8000/wizard/edit/1/, it displays the first form data correctly, and when I click submit, it is not taking me to step-2 of edit mode, i.e the URL changes to http://127.0.0.1:8000/wizard/create/.

如果在第一步单击编辑 url(如 /wizard/edit/1)上的 submit 时,保持相同的 url,则表单将获得其初始数据在下一步.但我不知道如何避免 url 更改为 /wizard/create

If upon clicking submit on edit url (like /wizard/edit/1) in the first step, same url is maintained then the form would get its initial data in next step. but I cannot figure out how to avoid the url from changing to /wizard/create

推荐答案

该错误看起来微不足道.在您的模板中,表单操作具有 wizards url,即 create 视图的 url.因此,当表单提交时,它会转到 /wizard/create.

The error looks trivial. In your template the form action has wizards url, which is url of create view. Hence when the form is submitted it goes to /wizard/create.

为了能够在两个视图中使用模板,您可以从 form 标签中删除 action 属性.表单将提交到可以创建或编辑的当前 url.

To able to use the template for both views, you can remove the action attribute from form tag. The form will be submitted to current url which can be create or edit.

因此将您的模板更改为具有 form 标记为

So change your template to have form tag as

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

<小时>

保存项目


To save item

将您的视图更新为:

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], })

这篇关于用于编辑的表单向导初始数据未在 Django 中正确加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆