モデルフォームフォームセットを使用すると、ユーザーは空の行を追加したり、AJAX を介して既存の行を削除したり、jQuery ソート可能を使用して行を再配置したりできます。
add/rearrange は両方とも、フォームに値を設定するだけで、ファイルの一部として保存されformset.save()
ます。
新しい行の追加メカニズムは、最後の既存の行のクローンを生成し、正しい入力名を生成しますform-0-id
。
前述のように、削除操作は AJAX を呼び出し、成功すると DOM から行を削除します。
再配置は、モデルの一部である非表示の重み入力を設定します。
[保存] を押すと、次の処理が順番に行われます。
- 完全に空白の行を取り除く
- #id_form-TOTAL_FORMS を正しい値に設定します
- 削除によるギャップを防ぐために、各行の各入力の name 属性をリセットして連続するようにします。
- フォームを送信します。
上記の手順からわかる限り、console.log
すべて期待どおりに実行されますが、エラーが発生するケースは次の場合です。
- 5行ある
- 行 6 に値を追加します
- 既存の行を削除します
- 保存をクリック
そして、私は得るinvalid literal for int() with base 10: ''
具体的には、このエラーは次の場所から発生しています。
lib/python2.7/site-packages/django/db/models/fields/__init__.py in get_prep_value
return int(value) ...
Local vars:
Variable Value
self <django.db.models.fields.AutoField: id>
value u''
これが失敗する理由がよくわかりません。自動フィールドの全体的なポイントは、まだ値が設定されていない場合に値を設定することだと思いました。
また、フォーム全体が保存される前に削除が行われない限り、新しい行を追加するためにフォーム全体が正常に機能するため、少し混乱しています。
フォームは何らかの方法でさまざまな入力名属性を記憶しており、新しいレコードを保存するのではなく、既存のレコードを更新しようとしていますか?
失敗したリクエストの POST データは次のとおりです。
Variable Value
form-INITIAL_FORMS u'6'
form-TOTAL_FORMS u'3'
form-MAX_NUM_FORMS u''
form-0-id u'38'
form-0-weight u'0'
form-0-disk_space u'1'
form-0-price_per_month u'1'
form-0-embedded_html u'1'
form-1-id u'45'
form-1-weight u'3'
form-1-disk_space u'2'
form-1-price_per_month u'2'
form-1-embedded_html u'2'
form-2-id u''
form-2-weight u'6'
form-2-disk_space u'3'
form-2-price_per_month u'3'
form-2-embedded_html u'3'
したがってform-2-id
、 auto がその仕事をすることを許可するのではなく、フィールド値を設定しようとして失敗しているようです。
以下は、送信が成功した POST データですが、フォームをロードし、新しい行を追加して保存しただけです。
Variable Value
form-INITIAL_FORMS u'2'
form-TOTAL_FORMS u'3'
form-MAX_NUM_FORMS u''
form-0-id u'38'
form-0-weight u'0'
form-0-disk_space u'1'
form-0-price_per_month u'1'
form-0-embedded_html u'1'
form-1-id u'48'
form-1-weight u'1'
form-1-disk_space u'2'
form-1-price_per_month u'2'
form-1-embedded_html u'2'
form-2-id u''
form-2-weight u'2'
form-2-disk_space u'3'
form-2-price_per_month u'3'
form-2-embedded_html u'3'
私が知る限り、すべてが失敗したリクエストと同じで、新しい行の ID は空白です。
完全なトレースバック: http://pastebin.com/AvegYgJA (SO には大きすぎました)
コピー アンド ペースト モードのトレースバック http://pastebin.com/9R68M6YX
解決策:
以下のダニエル・ローズマンの回答によるとid_form-INITIAL_FORMS
、更新された行の数に一致するように設定するだけで済みました。削除時に最初のフォームをデクリメントするのではなく、フォームを送信する前に次を JS に追加しました。
$('#id_form-INITIAL_FORMS').val(this.form.find('span.row-id input[value!=""]').length);
したがって、問題を永遠に解決します!