1

ストーリーとカテゴリを備えたブログのようなアプリケーションがあります。

class Category(models.Model):
    ...
class Story(models.Model):
    categories = models.ManyToManyField(Category)
    ...

多対多フィールドを持つモデルの新しいインスタンスを保存すると、オブジェクトがまだデータベースにないために問題が発生することがわかりました。この問題は通常、フォームの送信時に現れますが、これは でうまく回避できますstory_form.save(commit=False)。語るべき形がない状況はどうですか?私の場合、リモート送信を受け入れる API を構築したいと考えています。私は JSON が好きで、社内の他の多くのメッセージ (このサーバーからの送信メッセージを含む) は JSON であるため、次のメッセージを受信できるようにしたいと考えています。

{ "operation": "INSERT",
  "values": [
            { "datatype": "story",
              "categories": [4,6,8],
              "id":50,
              ...
            }
            ]
}

値をインスタンスに変換するファクトリを実装します。しかし、私は工場が操作の種類にできるだけとらわれないようにしたいと考えています。そう:

{ "operation": "UPDATE",
  "values": [
            { "datatype": "story",
              "categories": [4,6,8],
              "id":50,
              ...
            }
            ]
}

INSERT は id を無視し、UPDATE は既存のインスタンスを取得して上書きすることを除いて、同様に変換する必要があります。(リモート サブミッターは、特にキャッシュするカテゴリ オブジェクトを提供するフィードをリッスンするため、id でそれらを参照できますし、参照する必要がありますが、データベースとの直接通信はありません。)

私の本当の質問は、ManyToManyManager が関与する Django モデル オブジェクトのインスタンスをインフレートするのに最も簡単で一貫性のあるものは何かということです。私の知る限り、多対多フィールドを持つオブジェクトの挿入には、最初に新しい ID を取得する必要があるという理由だけで、2 つのデータベース ヒットが必要です。しかし、私の現在の厄介な解決策は、オブジェクトをすぐに保存して非表示にすることです。これにより、関数がそれを操作して、もう少し意味のあるものとして保存できます。saveID のないオブジェクトが一度保存され、いくつかのプロキシ フィールドが にコピーされてからcategories、再度保存されるように、1 ステップ アップするとオーバーライドされるようです。何よりも、問題を解決してくれる堅牢なマネージャー オブジェクトが必要です。おすすめは何ですか?

4

2 に答える 2

3

「私が知る限り、多対多フィールドを持つオブジェクトの挿入には、2 つのデータベース ヒットが必要です...」

だから何?

個々のデータベースへのアクセスを細かく管理することは、一般的に考えてみる価値はありません。Django がキャッシュを最適化できるように、最も単純でわかりやすいことを行います。

アプリケーションのパフォーマンスは、通常、ブラウザーへのダウンロードの遅さと、ページの一部であるすべての JPEG、CSS、およびその他の静的コンテンツによって支配されます。

データベースに 2 回アクセスせずに 2 つの主キー (多対多の関係) を作成する方法を頭を悩ませて考えるのに費やした時間は、うまくいきません。通常、2 つの PK は 2 つのデータベース アクセスです。


編集

「...エラーでデータベースを散らかします...」

Django にはトランザクションがあります。http://docs.djangoproject.com/en/dev/topics/db/transactions/#managing-database-transactionsを参照してください。@transaction.commit_manuallyデコレータを使用します。

「後で発生することを意図した検証を強制します」

意味がありません-これを説明するために質問を更新してください。

于 2009-04-06T22:34:55.490 に答える
2

S.Lottの投稿にコメントしたところ、彼の答えが一番だと思います。彼の言う通りです。データベースへの2回のヒットを回避することが目標であれば、不必要な苦痛の世界にいることになります。

ただし、ModelFormへの参照を読んで、何らかの方法で公式の保存を延期できる解決策を探している場合は、のsave_instance()関数を確認することをお勧めしますforms.models。内部機能save_m2mは、フォームの遅延多対多保存をどのように実行するかです。フォームのないモデルに何かを実装することは、基本的に同じ原則に従います。

そうは言っても、S.Lottの投稿に戻ると、ModelFormの場合と実際のモデルの場合は多少異なります。フォームはブラウザで編集される「安全な」データセットのみを公開するため(何らかの方法でフィルタリングされるか、ユーザーが編集してはならない重要なフィールドを除外するため「安全」)、次のような合理的な設計上の期待があります。保存する前に、フォームから派生したモデルに重要な情報を追加する必要がある場合があります。これがdjangoに。がある理由commit=Falseです。

モデルを直接インスタンス化する場合、この期待は低くなります。ここでは、モデルAPIにプログラムでアクセスできるため、そのAPIを直接使用する方が、一般化された間接参照よりも保守が簡単で、エラーが発生しにくいことがわかるでしょう。ファクトリの概念を描いている理由は理解できますが、この場合、あらゆる種類のモデルに対して防弾の一般化を作成する努力は、それだけの価値がない複雑さであることに気付くかもしれません。

于 2009-04-06T23:04:11.940 に答える