【问题标题】:form wizard initial data for edit not loading properly in Django?用于编辑的表单向导初始数据在 Django 中未正确加载?
【发布时间】:2014-08-02 03:03:00
【问题描述】:

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

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

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

【问题讨论】:

  • 我看到的一个问题是您不需要将RequestContext() 传递给向导视图调用,因此请尝试删除它。
  • @Rohan 我尝试删除 RequestContext() 但这没有帮助
  • @Rohan:我在编辑中添加了更多信息。我希望你能帮忙。谢谢

标签: django django-forms django-views django-formwizard


【解决方案1】:

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

为了能够为两个视图使用模板,您可以从form 标记中删除action 属性。表单将提交到可以创建或编辑的当前 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], })

【讨论】:

  • 谢谢,有帮助。但在编辑模式下,模型不会被覆盖。即不保存更改。你能帮忙解决什么问题吗?
  • @brainstorm,在你看来,如果你得到item,你实际上并没有用它来保存。
  • 感谢您的评论,我现在在done method 中插入了item.save()(您可以在上面的代码中看到)。但这并没有保存编辑模型。你认为我应该将item 保存在其他地方吗?
  • :工作就像一个魅力。非常感谢。你也许可以在这篇文章上帮助我:你已经评论了这篇文章。但我看到两份图片正在上传(一份到 fileStorage,一份到上传路径)。如何避免? stackoverflow.com/questions/24176068/…
猜你喜欢
  • 2011-02-04
  • 1970-01-01
  • 2013-05-05
  • 1970-01-01
  • 2022-08-11
  • 2016-07-16
  • 1970-01-01
  • 1970-01-01
  • 2016-11-06
相关资源
最近更新 更多