我已经写了我希望成为可重复使用的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都会有所不同。
任何人都可以建议一种解决方法吗?
答案 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)