web-dev-qa-db-ja.com

Django同じテーブルの2つの外部キーを持つモデル

同じテーブルの2つの外部キーを持つDjangoモデルが必要でした。これは、従業員用の2つの列を持つイベントテーブルです。「actor」と「receiver」。

エラー:1つ以上のモデルが検証されませんでした:tasks.task:中間モデルTaskEventには、従業員に対する複数の外部キーがありますが、これはあいまいで許可されていません。

これをモデル化するより良い方法はありますか?ありがとう

TaskEvent_to_Employeeテーブルを追加すると思います。その中には2つのレコードがあり、各TaskEventに関連する2人の従業員ごとに1つです。誰でも簡単な回避策を知っていますか?

42
Josh

私はまだこれをしていませんが、inspectdbを使用して、まさにそれを行う既存のDBからmodels.pyファイルを生成します-これはinspectdbがスローしたものなので、動作するはずです:

creator = models.ForeignKey(Users, null=True, related_name='creator')
assignee = models.ForeignKey(Users, null=True, related_name='assignee')

それがあなたのために働くことを願っています-それがなければ、私も問題を抱えています。

84
Technical Bard

あなたが探しているのはForeignKeyFieldsのrelated_nameプロパティだと思います。これにより、同じテーブルを参照できますが、Django関係の特別な名前を指定します。

より詳しい情報:

7
Justin Abrahms

エラーメッセージから、throughへのManyToManyField引数、 ドキュメントの状態

中間モデルをセットアップするとき、ManyToMany関係に関係するモデルに外部キーを明示的に指定します。この明示的な宣言は、2つのモデルの関係を定義します。

中間モデルにはいくつかの制限があります。

  • 中間モデルには、ターゲットモデルへの外部キーが1つだけ含まれている必要があります(この例ではPersonになります)。複数の外部キーがある場合、検証エラーが発生します。
  • 中間モデルには、ソースモデルへの外部キーが1つだけ含まれている必要があります(この例ではグループになります)。複数の外部キーがある場合、検証エラーが発生します。
7
Jonny Buchanan

related_name を使用することが私の解決策でした:

class Sample(models.model):
    ...

class Mymodel(models.model):
    example1 = models.ForeignKey(Sample, related_name='sample1')
    example2 = models.ForeignKey(Sample, related_name='sample2')
1
Alex Jolig

2つの列が1つのテーブルの一部であるという事実は、2つのフィールドが関連していることを意味しているため、それらを個別に参照することは理想的ではありません。モデルのForeignKeyは、参照しているテーブルの主キーである必要があります。

event = models.ForeignKey('event')

次に、列を次のように参照します。

foo.event.actor
foo.event.receiver

必要に応じて、クラス/モデルがプロパティを持つ外部属性を参照する方法を変更することもできます。クラスでは、次のことを行います。

@property
def actor(self):
  return self.event.actor
@property
def receiver(self):
  return self.event.receiver

これにより、foo.actorおよびfoo.receiverを呼び出すことができますが、長いほど、foo.event.actorはよりPythonicになると思います

0
awithrow