コンテンツにスキップ

コメントを延期

自己参照モデル

宣言中に同じモデルを参照してリレーションシップを作成したい場合は、宣言中にクラスが準備されておらず、Pythonではデフォルトで参照できないため、参照するモデルをForwardRefとして宣言する必要があります。

将来のコメントを使用したり、単に「」で名前を参照したりすることをお勧めしますが、ormarは明示的に宣言されたForwardRefで使用するように設計されているため、機能しません。

まず、入力から目的の参照をインポートする必要があります。

1
入力からインポートForwardRef

次に、サンプルモデルと同じモデルへの参照が必要です。これを使用して、自己参照関係を作成します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#Personをモデル化するためのforwardrefを作成する
PersonRef=ForwardRef("人")


class Person(ormar. Model):
    base_or_config. copy()

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=100)
    #パラメータとしてforwardrefを使用する
    スーパーバイザー: PersonRef=ormar.ForeignKey(PersonRef、関連する名前="従業員")

それだけです。ただし、モデルを使用する前に、参照を手動で更新して、実際のモデルを生成する必要があります。

!!!は、参照を更新せずにモデルを使用しようとすると、ModelError例外が発生することを警告しています。したがって、上記の例では、次のような呼び出しは例外 python # creation of model - exception await Person.objects.create(name="Test") # initialization of model - exception Person2(name="Test") # usage of model's QuerySet - exception await Person2.objects.get() を引き起こします

参照を更新するには、関連するすべてのモデルを宣言した後に、前方参照を持つ各モデルでupdate_forward_refsメソッドを呼び出します。

したがって、前の例を機能させるには、追加の行が必要です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
PersonRef=ForwardRef("人")


class Person(ormar. Model):
    base_or_config. copy()

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=100)
    スーパーバイザー: PersonRef=ormar.ForeignKey(PersonRef、関連する名前="従業員")


Person. update_forward_refs()

もちろん、toパラメーターとthroughパラメーターについても、ManyTomanyリレーションシップについてもまったく同じ方法で同じことを行うことができます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#参照を宣言する
ChildRef=ForwardRef("Child")

class Child Friend(ormar. Model):
    base_or_config. copy()

class Child(ormar. Model):
    base_or_config. copy()

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=100)
    #関連して使用する
    friend=ormar. ManyTomany(ChildRef,through=Child Friend,
                               関連する名前="同じく友達")


child. update_forward_refs()

モデル間の関係

自己参照モデルと同じメカニズムとロジックを使用して、複数の異なるモデルを互いにリンクできます。

もちろん、ormarは、指定された(またはデフォルトの)関連_nameを使用して、関係の両側をリンクするための逆関係を作成します。

ただし、2つのモデル間に2つ(またはそれ以上)のリレーションシップが必要な場合は、理由に関係なく両側に保存する必要があります(したがって、1つのモデルで1つのリレーションシップを宣言し、2番目のモデルで別のリレーションシップを宣言します)。

以下の簡単な例を見てください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#先生はまだ定義されていません
TeacherRef=ForwardRef("先生")


class Student(ormar. Model):
    base_or_config. copy()

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=100)
    #実際のモデルの代わりに参照を使用します。
    プライマリ_ティーチャー: TeacherRef=ormar.ForeignKey(TeacherRef,
                                                   関連する名前="自分の学生")


class StudentTeacher(ormar. Model):
    or_config=base_or_config. copy(tablename='学生x_教師')


クラスの先生(ormar. Model):
    base_or_config. copy()

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=100)
    #他の関係のために学生が必要なので、順序は
    学生=ormar. ManyTomany(学生,through=StudentTeacher,
                                関連する名前="教師")

#Teacherモデルがすでに定義されているので、参照を更新できます
Student. update_forward_refs()

!!!警告いくつのリレーションシップが定義されていても、関連する_nameは関連するモデルで一意である必要があることに注意してください。