1

この件に関するリソースはほとんど使い果たしたので、コミュニティに質問を送信する必要があります。

シナリオ:

私の urls.py ファイルには、次のようなパターンがあります。

url(r'^entry_form/(?P<sheet_id>\d+)/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])),

ユーザーが「127.0.0.1/myapp/entry_form/77」のような URL にアクセスすると、Django に Sheet1 をレンダリングさせようとしていますが、フィールドの 1 つに値「77」が最初に入力されています。

セロイ:

私の 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
                             )
             )
        #Now set the initial value of the field to sheet_id from url pattern
        self.fields['sheet_field'].initial = str(sheet_id)+'-'+ str( time() ).replace('.','_')
        #??? Not sure where to get sheet_id from???

最後の行に「sheet_id」という名前の変数があることに注意してください。これは、ユーザーが入力した URL パターンからの値「77」である必要があります。

問題:

これまでのところ、forms.py または views.py ファイルの URL パターンから値「sheet_id」にアクセスする方法がわかりません。これはクラスベースのビューであるため、「sheet_id = None」というキーワードを単純に作成することはできません。別名、次のようなものは機能しません。

class SheetWizard(SessionWizardView, sheet_id=None):
    #this breaks

request.GET と「127.0.0.1/myapp/entry_form/?sheet_id=77」のような URL を使用して、views.py にデータを取得できましたが、それを SessionWizardView の最初のフォームにパイプする方法がわかりません。ユーザーセッション。

誰かが私を助けてくれれば幸いです。そして、あなたの親切な知恵に感謝します!

4

2 に答える 2

1

ウィザードのdispatch方法を使用します。

def dispatch(self, request, *args, **kwargs):
    self.sheet_id = kwargs.get('sheet_id', None)
    return super(SheetWizard, self).dispatch(request, *args, **kwargs)

次にself.sheet_idwithinget_form_initialメソッドを使用して、フォームの初期値を設定します。

于 2014-11-09T07:51:54.427 に答える
1

私を正しい方向に向けてくれた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 データをセッションに保存することは、これまでに見つけた中で最もクリーンで洗練された修正でした。

お役に立てれば!!

于 2014-11-09T17:44:12.807 に答える