感谢 mariodev 为我指明了正确的方向。
我发现这种代码组合适用于我的应用程序:
[urls.py]
url(r'^entry_form/(?P<sheet_id_initial>\d+)/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])),
[视图.py]
class SheetWizard(SessionWizardView):
#some code here
def dispatch(self, request, *args, **kwargs):
self.sheet_id_initial = kwargs.get('sheet_id_initial', None)
return super(SheetWizard, self).dispatch(request, *args, **kwargs)
def get_form_initial(self, step):
initial = self.initial_dict.get(step, {})
if int(step) == 0:
initial.update({ 'sheet_id_initial': self.sheet_id_initial })
return initial
[表格.py]
class Sheet1(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(Sheet1, self).__init__(*args, **kwargs)
#create a helper object
self.helper = FormHelper(self)
#dont render the form tags
self.helper.form_tag = False
#Make a nice layout
self.helper.layout = Layout(
TabHolder(
Tab(
'Sheet Information', #Tab name text
PrependedText('sheet_field', 'Django-'), #The field with prepended text
)
)
#finally lets set the initial values
if 'initial'in kwargs:
initial = kwargs.pop('initial')
print initial
if 'sheet_id_initial' in initial:
sheet_id_initial = initial.pop('sheet_id_initial')
#this is where the value from sheet_id_initial is initialized in the field :)
self.fields['sheet_id_initial'].initial = str(sheet_id_initial)+'-'+ str( time() ).replace('.','_')
然而,这确实产生了一个新问题。我现在可以访问第一个表单,并且 URL 模式中 sheet_id_initial 的值已按预期添加到表单字段中,但是当按下提交按钮时,由于 POST 未将 sheet_id_initial 部分添加到请求网址。
[返回页面]
""""
找不到页面 (404) 请求方法:POST 请求 URL: http://192.ip.address.1:8001/sheets/entry_form/
使用 first_project.urls 中定义的 URLconf,Django 按以下顺序尝试了这些 URL 模式:
^admin/
^Users/
^sheets/ ^entry_form/(?P<sheet_id_initial>\d+)/
当前 URL sheet/entry_form/ 与其中任何一个都不匹配。
您看到此错误是因为您的 Django 设置文件中有 DEBUG = True 。将其更改为 False,Django 将显示标准 404 页面。
""""
[附加信息]
要更改从 URL 模式或 POST 数据获取 sheet_id 变量的方式,非常简单:
首先将 urls.py 中的正则表达式模式更改为简单的匹配,例如:
urlpatterns = patterns('',
url(r'^entry_form/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])),
#url(r'^entry_form/(?P<sheet_id_initial>\d+)/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])), #'sheet_id_initial' would be picked up by "self.sheet_id_initial = kwargs.get('sheet_id_initial', None)" in SheetWizard.dispatch()
然后在 views.py 中更改调度覆盖方法中的分配,如下所示:
class SheetWizard(SessionWizardView):
def dispatch(self, request, *args, **kwargs):
#self.sheet_id = kwargs.get('sheet_id_initial', None) #used to grab sheet_id_initial from url pattern
if self.request.GET.has_key('sheet_id_initial'):
self.sheet_id_initial = self.request.GET['sheet_id_initial'] #used to grab sheet_id_initial from QueryDict
return super(SheetWizard, self).dispatch(request, *args, **kwargs)
最后,如果您收到 MultiValueDictKeyError,我在 get_form_initial() 中添加了一个 try-except 块,如果 POST 数据存在(但我不确定这是否是最好的方法来处理这个..)
所以在views.py中将这些行添加到get_form_initial():
class SheetWizard(SessionWizardView):
def get_form_initial(self, step):
initial = self.initial_dict.get(step, {})
if step == "0":
try:
self.sheet_id_initial #check for variable existence
#if we get past this line then the variable existed and we can update initial data
initial.update({ 'sheet_id_initial': self.sheet_id_initial })
except:
#variable didn't exist so lets just move on..
pass
return initial
[更新 - 迄今为止最好的修复]
这个 sessionwizard 和基于类的视图可能有点棘手。我发现这两种以前的方法都以某种方式存在一些缺陷,并意识到我把事情复杂化了一点。但是之前的大部分代码都是必不可少的,但我将 POST 数据存储在会话中并在不同 URL 的表单中访问它,而不是 POST 或 URL 模式!
现在我有一个表单,用户从地址开始:“ http://192.ip.address.1:8001/sheets/start/ ”,表单中有两个字段:“part_id_initial”和“sheet_id_initial”
当按下提交时,用户将被重定向到:“ http://192.ip.address.1:8001/sheets/entry_form/ ”但是 HTTP 有一个限制,即 POST 数据不能与重定向一起使用。
因此您可以通过修改上述代码来保存会话 POST 数据并以另一种形式使用它:
网址.py
url(r'^start/', 'process_forms.views.GetStarted'),
url(r'^entry_form/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])),
视图.py
def GetStarted(request):
form = gettingStarted(request.POST or None)
if request.method == 'POST':
if form.is_valid():
data = form.cleaned_data
request.session['_old_post'] = request.POST #Store POST to be passed to SheetWizard
return redirect('/sheets/entry_form/')
return render_to_response('get_started.html',
locals(),
context_instance=RequestContext(request))
class SheetWizard(SessionWizardView):
def dispatch(self, request, *args, **kwargs):
old_post = request.session.get('_old_post') #Retrieve old POST data to set initial values on session form
if old_post.has_key('sheet_id_initial') and old_post.has_key('part_id_initial'):
self.sheet_id_initial = old_post['sheet_id_initial'] #used to grab sheet_id from QueryDict
self.part_id_initial = old_post['part_id_initial'] #used to grab sheet_id from QueryDict
return super(SheetWizard, self).dispatch(request, *args, **kwargs)
其余的与上面几乎完全相同。将 POST 数据保存到会话中是迄今为止我发现的最干净、最优雅的修复。
希望这可以帮助!!