このオブジェクトのインスタンスを作成するときに、別のモデルのインスタンス (B と呼びます) を content_object フィールドの初期化子として渡します (コンストラクターの kwargs を介して)。
A を作成する前に B を保存しないと、A を保存するときに content_object_id が NULL としてデータベースに保存されます。A のコンストラクターに渡す前にB を保存すると、すべて問題ありません。
それは論理的ではありません。A.save() を実行するときに関連オブジェクト (B) の ID がフェッチされ、B がまだ保存されていない場合は何らかの例外をスローする必要があると想定しましたが、黙って失敗するだけです。オブジェクトを廃棄するだけでなく、常にオブジェクトを保持する意思があるかどうかまだわからないため、現在のソリューション (事前に B を保存) は好きではありません。また、パフォーマンスに関する考慮事項もあります。別のデータを追加するとどうなるでしょうか。すぐにもう一度保存します。
class BaseNodeData(models.Model):
...
extnodedata_content_type = models.ForeignKey(ContentType, null=True)
extnodedata_object_id = models.PositiveIntegerField(null=True)
extnodedata = generic.GenericForeignKey(ct_field='extnodedata_content_type', fk_field='extnodedata_object_id')
class MarkupNodeData(models.Model):
raw_content = models.TextField()
次のようにするとします。
markup = MarkupNodeData(raw_content='...')
base = BaseNodeData(..., extnodedata=markup)
markup.save()
base.save()
# both records are inserted to the DB but base is stored with extnodedata_object_id=NULL
markup = MarkupNodeData(raw_content='...')
base = BaseNodeData(..., extnodedata=markup)
base.save()
markup.save()
# no exception is thrown and everything is the same as above
markup = MarkupNodeData(raw_content='...')
markup.save()
base = BaseNodeData(..., extnodedata=markup)
base.save()
# this works as expected
もちろん、私はこの方法でそれを行うことができますが、何も変わりません:
base = BaseNodeData(...)
base.extnodedata = markup
私の質問は、これは私が報告すべきジャンゴのバグですか、それとも何か間違ったことをしているのかもしれません。GenericRelations のドキュメントは厳密には冗長ではありません。