2016-06-29 24 views
0

この作業を終日行ってみました。私はエントリーであるメインモデルを持っています。エントリにはいくつかのシフトが含まれます。これは勤務時間を保存するアプリの一部です。ここでは、エントリを作成するためのビューがあります:Formset:モデルを保存することができません

class EntryCreateView(FormView): 
    template_name = 'entry/create.html' 
    form_class = AddWorkDay 
    success_url = reverse_lazy('time_manager:index') 

    def get(self, request, ordinal=None, *args, **kwargs): 
     """ Initiates with a blank form or will populate the day field with the day represented by the passed 
      ordinal. """ 
     if ordinal: 
      day = datetime.datetime.fromordinal(int(ordinal)) 
      form = AddWorkDay(initial={'day': day}) 
     else: 
      form = AddWorkDay() 
     formset = ShiftFormSet() 

     return render(request, self.template_name, {'form': form, 'formset': formset}) 

    def post(self, request, ordinal=None, *args, **kwargs): 
     form = AddWorkDay(data=request.POST) 
     formset = ShiftFormSet(data=request.POST) 
     errors = [] 
     shifts = [] 

     if form.is_valid() and formset.is_valid(): 
      # Build entry. 
      entry  = form.save(commit=False) 
      entry.owner = request.user 
      errors.extend(entry.validate(request.user)) 

      # Build shift. 
      for form in formset: 
       shift  = form.save(commit=False) 
       shift.entry = entry 
       shifts.append(shift) 
       errors.extend(shift.validate(request.user)) 

      if len(errors) == 0: 
       entry.save() 
       for shift in shifts: 
        shift.save() 
       return HttpResponseRedirect(reverse('time_manager:index')) 

     return render(request, self.template_name, {'form': form, 'formset': formset, 'errors': errors, 'shifts': shifts, 'entry': entry}) 

私がシフトを押し、保存してエントリを入力しようとすると、それは言って終了します。 「IntegrityError time_manager /エントリー/時/作成/ NOT NULL制約が失敗しました: 「shift_shift.entry_id」。私はシフトに何が間違っているのかを調べようとしました。そのため、シフトが保存されているブロック(「ifen(エラー)」から「HttpResponseRedirectを返す」)をコメントアウトして、フォームのビューに戻るようにしました。私はテンプレートに{{シフト}}を入れてそこにあるものを見ます。 "noReverseMatch at/time_manager/entry/create/ 引数 '()'とキーワード引数 '{' pk ':None}'を指定して '編集'を行います。 )は、{'url%}タグを使用して、存在しないビューを参照しようとしているかのように、[' time_manager/entry/shift/edit /(?P(\ d +))/ $ ']だから私は、フォームセットのフォームを保存しようとすると何かがうまくいかないと推測しています。しかし、私は何度もdjangoのドキュメントを読んで、これはフォームセットのフォームを格納する方法です、そうではありませんか?

+1

あなたは保存をコメントアウトしているので、オブジェクトは保存されないため、pkはnullになります。 –

+0

保存部分がコメントアウトされていない場合、null制約が発生します。私はそれをコメントアウトしたので、フォームビューに戻り、変数の内容を表示することができました。しかし、shiftの内容を表示しようとすると、ビューが終了します。 – user2660930

+0

urlタグを使用しているテンプレートを表示する必要があります。 –

答えて

1

新鮮な頭で私は自分のコードを見て、それが私に起こりました。私は、エントリと各シフトが正しく構築されていることを確認した後、ルールに違反しない場合にのみ保存します。上記のように、commit = Falseの両方で保存しています。ただし、エントリにはまだプライマリキーが割り当てられていません。主キーは、シフトモデルのForeignKeyFieldに必要なものです。だからDjangoはそれを保存できませんでした。
メソッドの順序を多少変更しました。これは作業コードです:

2回目のエントリ(commit = Falseなし)が保存され、shiftに割り当てられていることに注意してください。