私を正しい方向に向けてくれたmariodevに感謝します。
私のアプリケーションでは、次のコードの組み合わせが機能することがわかりました。
[urls.py]
url(r'^entry_form/(?P<sheet_id_initial>\d+)/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])),
[views.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
[forms.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 page not found が返されます。リクエストURL.
【戻ってきたページ】
""""
ページが見つかりません (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、sheets/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
[更新 - これまでで最高の修正]
このセッション ウィザードとクラス ベースのビューは少し扱いにくい場合があります。私は、これらの以前のアプローチの両方に、何らかの形で何らかの欠陥があることを発見し、物事を少し複雑にしすぎていることに気付きました. しかし、以前のコードのほとんどは不可欠でしたが、POST または URL パターンの代わりに、POST データをセッションに保存し、異なる URL のフォーム間でアクセスしています!!
これで、ユーザーが次のアドレスから開始するフォームができました: " http://192.ip.address.1:8001/sheets/start/ " このフォームには、"part_id_initial" と "sheet_id_initial" の 2 つのフィールドがあります。
送信が押されると、ユーザーは「http://192.ip.address.1:8001/sheets/entry_form/」にリダイレクトされますが、POST データをリダイレクトできないという HTTP の制限があります。
上記のコードを次のように変更することで、セッション POST データを保存し、別の形式で使用できます。
urls.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 データをセッションに保存することは、これまでに見つけた中で最もクリーンで洗練された修正でした。
お役に立てれば!!