如何在django中路由多部分表单

时间:2017-10-03 21:48:46

标签: python django

我是django的新手。

我希望我的用户能够下订单。对于这种顺序,用户上传csv。应用程序解析,CSV,序列化数据,然后需要向用户显示包含数据的新视图和“确认订单”按钮。我不知道如何在django中这样做。

class UploadSampleSheetView(LoginRequiredMixin, FormView):

    form_class = UploadSampleSheetForm
    template_name = 'pages/upload.html'

    def form_valid(self, form):

        uploaded_sample_sheet = self.request.FILES['uploaded_sample_sheet']
        sample = _parse_sample_sheet_to_sample_model(uploaded_sample_sheet)
        sample.save()

        return super().form_valid(form)

    def get_success_url(self):
        return reverse("orders:create") # how do I return another view populated with data here? 


class CreateOrderView(LoginRequiredMixin, CreateView):

    model = Order
    form_class = NewOrderForm
    template_name = 'pages/complete_order.html'

我正在寻找的是某种方式,成功时,UploadSampleSheetView可以返回带有sample数据的CreateOrderView。

一般来说,我很乐意指出有关如何构建像这样的用户流的参考。一个人如何看待另一个?我看到很多return HttpResponseRedirect('url')看起来有点混乱。如何围绕视图传递数据?

3 个答案:

答案 0 :(得分:1)

FormViews应该返回HttpResponseRedirects。他们接收数据,处理数据,并将您重新路由到一个有意义的地方。我想你的问题是,我怎样才能到达适当的地方。

文档对此并不十分清楚,因此这是一个非常有效的问题。但是,您可以覆盖get_success_url以接受参数。所以,你要加上这个:

def get_success_url(self, sample_id):
    return reverse('create_order', kwargs={"pk" : sample_id})

并将form_valid更改为

def form_valid(self, form):
    uploaded_sample_sheet = self.request.FILES['uploaded_sample_sheet']
    sample = _parse_sample_sheet_to_sample_model(uploaded_sample_sheet)
    sample.save()
    return HttpResponseRedirect(self.get_success_url(sample.id))
不要担心,你不会因跳过super()而错过任何事情.form_valid() - the docs(稍微向下滚动)说所有{{1}默认情况下会重定向到form_valid

答案 1 :(得分:0)

我认为您正在寻找Django Session。如果你想深入了解,这是一份广泛的文件。

它包括您正在寻找的示例。

答案 2 :(得分:0)

您可以使用Form Wizard

  

Django附带一个可选的“表单向导”应用程序,可以跨多个Web页面拆分表单。它在其中一个后端维护状态,以便可以延迟完整的服务器端处理,直到提交最终表单。

     

如果您有一个冗长的表单,在单个页面上显示太笨重,您可能想要使用它。第一页可能会询问用户核心信息,第二页可能会询问不太重要的信息等等。

使用起来比较难,但非常实用且灵活。

# views.py
from formtools.wizard.views import SessionWizardView

class MyView(SessionWizardView):
    template_name = 'pages/wizard_steps.html'
    template_name_done = 'pages/wizard_done.html'

    form_list = (
        ('upload', UploadSampleSheetForm),
        ('confirm', NewOrderForm)
    )

    def done(self, form_list, **kwargs):
        # you can get all forms data here and process it as you want
        return render(self.request, self.template_name_done, {
            'form_data': [form.cleaned_data for form in form_list],  
        })

    def process_step(self, form):
        if isinstance(form, UploadSampleSheetForm):
            # Example. You can put here some additional manipulations
            pass
        return super().process_step(form)

和模板

<!-- wizard_done.html -->
{% if wizard.steps.current == 'upload' %}
    {% include 'pages/wizard_upload.html' %}
{% elif wizard.steps.current == 'complete' %}
    {% include 'pages/wizard_complete.html' %}
{% endif %}