如何使我的帖子表单处理更灵活

时间:2012-09-11 18:40:28

标签: python django

我已经写了我希望成为可重复使用的Django应用程序,但我对如何使帖子表单处理灵活有点难题。我的视图代码的简化版本如下:

def do_form(request, entity_id, template_name, success_url):

    form = MyForm(request.POST or None)

    if request.method =='POST':
        if form.is_valid():

            #do some business logic

            return HttpResponseRedirect(finished_url)
    return render_to_response(template_name, 
                              {'form': form},
                             context_instance=RequestContext(request))

我已按照James Bennets的书“Practical Django Projects”中的建议进行操作,因此您现在可以在url conf中配置模板和成功URL,例如我的url conf可能如下所示:

urlpatterns = patterns('myapp.views',


          url(r'^do/(?P<entity_id>\d+)/$', 
          view = 'do_form',
          name = 'do_form_view',
          kwargs={'template_name':'form.html',
                    'success_url':'/finish/'},),

          url(r'^finish/$', 
          view = 'finish',
          name = 'finish_view')
)

这一切都非常好,但是当我在现实世界的应用程序中使用它时,我发现自己处于这种形式处于某个工作流程中间的情况,我希望成功的URL类似于/continue/<workflow_id>/,问题是你只能在url conf中有一个硬编码的url,而且每次点击do_form代码时workflow_id都会有所不同。

任何人都可以建议一种解决方法吗?

3 个答案:

答案 0 :(得分:1)

您可以通过更改以下内容来实现这一目标。

views.py do_form()

return HttpResponseRedirect更改为

return HttpResponseRedirect('/continue/%s' %(workflowid))

urls.py 中,您可以

url(r'^continue/(?P<workflowid>\d+)/$', 
          view = 'continue',
          name = 'continue_view')

以及 views.py

中的continue()视图
def continue(request, workflowid=None):
 ...

这样..无论何时访问没有数字的网址/continue/,工作流ID都将等于None。每隔一段时间,如果你有附加的工作流程,例如与/continue/23/类似,然后在continue()视图中,您可以通过变量workflowid访问该ID。

答案 1 :(得分:1)

当您将假设的“灵活”success_url传递给视图时,该视图必须提供所需的标识符。因此,如果您与网址和视图不匹配,我们无法避免两者之间出现“违约”。

因此,如果我们要拥有灵活的URL,则必须强制执行某种合同,如果我们通过URL的特殊语法执行此操作,则不会失去一般性:

  'finished_url':  '/finish/<workflow_id>/'

然后,当然,视图必须通过字符串替换来实例化变量,以履行合同的一面:而不是

  return HttpResponseRedirect(finished_url)

你会有

  return HttpResponseRedirect(finished_url.replace('<workflow_id>', WorkflowID))

这应该让事情变得相当简单。

重用代码时,您必须记住,<workflow_id> 该应用用于调用工作流ID 的任何内容,这就是我使用复杂字符串的原因,例如{{1而不是workflow_id或者id

编辑:我打算为下一步添加代码(在完成参数中拦截工作流程ID),但我看到keithxm23击败了我: - )

答案 2 :(得分:0)

你可以像人们多年来“覆盖”Django基于函数的通用视图一样:简单地将视图包装在另一个视图中:

def custom_do_form(request, entity_id, template_name, success_url):
    template_name = some_method_to_get_template()
    return do_form(request, entity_id, template_name, success_url)