2009年12月22日火曜日

Django の分からないところ

調べてみたけど分からなかったことリスト。(随時更新)
知っている方、教えていただけると本当に助かります。
あるモデルの一部のフィールドのみ編集可能にしてそれ以外は表示だけさせたい

複数のフィールドを持つモデルの値のうち一部を書き換える場合。例えばこんなかんじで。オブジェクトとそれをインスタンスとして作ったフォームオブジェクトをコンテキストに突っ込めばテンプレートから参照はできるけれど、なんだか冗長だし、複数のインスタンスを一度に編集できるようにしたい場合などはテンプレートにリストが2つ渡って対応付けしたりとややこしくなる。
フォームオブジェクトから value を抜き出して表示することがテンプレートからできれば万事解決なんですが、そういう方法ってないのだろうか。

複合キーを扱いたい

とりあえず現時点では扱えないらしい?
複合キーにすべきフィールド以外に主キーをたてておく。
データモデリング的によろしくないが実用上は複合キーで検索してリレーションには主キーを使えばまあ問題ないか。
(追記) モデルオブジェクトの Meta 内で unique_together(フィールド名リスト) で指定可能だった。

ModelForm での is_validがよくわからない

何をチェックしているのかよくわからない。モデルで指定した「省略可能」 (blank=True) とか 「ヌル値許容」 (null=True) とかの条件にフォーム内データが合致しているか否かをチェックしているのだろうとは思うけれど、暗黙の主キーである id フィールドがフォームに入ってると問答無用で False を返される。なぜ?
追記: 主キーの値の重複が不正と見なされている。下に書いたように主キーを指定した場合は update になるので問題ないはずだが、なぜか invalid となっている。なぜ?
追記: ここに答えがあった。つまり
  1. 主キーは POST パラメータではなく URL で渡す
  2. そこから取得した主キーをもとにして既存レコードのインスタンスを取得する
  3. そのインスタンスと POST パラメータを一緒に渡してインスタンスを作り直す
が正解の模様。

Django は insert と update を勝手に呼び分ける

save が呼ばれたデータの Primary Key が既にデータベースに存在すれば update、なければ insert を実行する。Primary Key が Python 的に False である場合は update する。例えば Primary Key の値が入ってないデータは insert になるので、Primary Key 以外に unique 制約を持つデータなどは、既存データのつもりでうっかり Primary Key のフィールドを入れずに save したりすると insert されて unique 制約に引っかかる、とかありそう。

メモリリーク?

大量データ(300万レコードほど)をデータベースに突っ込むために Django のモデルをインポートして作成したスクリプトをコマンドラインで走らせているとどんどんメモリを食う。やっていることはレコードごとに関数を読んで、その中で新たにモデルのインスタンスをローカル変数に代入して save するというだけ。関数から抜けた後にどこかの時点で GC にかかることを期待していたのだけれど、どうもそうなってはくれない模様。

0 件のコメント:

コメントを投稿