コンテンツにスキップ

関係

現在、ormarは2種類の関係をサポートしています:

  • foreignkeyフィールドを持つ1対多(および1対多)
  • ManyTomanyフィールドを持つ多対多

以下に、各リレーションシップの非常に基本的な定義例を見つけることができます。

メソッド、可能性、定義などの詳細については、ドキュメントの次のセクションをお読みください。

外部キー

複数対1のリレーションシップを定義するには、外部キーフィールドを使用します。

 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
from typing import Dict, Optional, Union

import databases
import ormar
import sqlalchemy

DATABASE_URL = "sqlite:///test.db"

ormar_base_config = ormar.OrmarConfig(
    database=databases.Database(DATABASE_URL), metadata=sqlalchemy.MetaData()
)


class Department(ormar.Model):
    ormar_config = ormar_base_config.copy()

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)


class Course(ormar.Model):
    ormar_config = ormar_base_config.copy()

    id: int = ormar.Integer(primary_key=True)
    name: str = ormar.String(max_length=100)
    department: Optional[Union[Department, Dict]] = ormar.ForeignKey(Department)

!!!ヒント1対多のリレーションシップの詳細については、外部キーセクションを参照してください

逆外部キー

1対多の関係の定義も自動的に登録してくれるForeignKeyを使っています。

したがって、上記の例では。

1
2
3
4
5
6
7
8
class Department(ormar. Model):
    base_or_config. copy()

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=100)
    #以下のような仮想フィールドがあります。
    コース:オプション[リスト[コース]]=ormar. ForeignKey(コース、仮想=True)
    自分で定義するのではなく、ormarが自分のために定義することに注意してください。

!!!ヒント複数対1のリレーションシップ(つまり、生成されたフィールドの名前の変更)の詳細については、外部キーセクションにアクセスしてください

!!!tip ReverseforeignKeyを使用すると、queryset-proxyを使用して関連するモデルをクエリできます。

1
`await department.courses.all()` を使用して、特定の部門などにのみ関連するデータを取得できます。

多対多

多対多のリレーションシップを定義するには、ManyTomanyフィールドを使用します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
class Category(ormar. Model):
    ormar_config=ormar. OrmarConfig
        データベース=データベース、
        metadata=メタデータ,
        tablename="カテゴリ",
    )

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=40)

class Post(ormar. Model):
    ormar_config=ormar. OrmarConfig
        データベース=データベース、
        metadata=メタデータ,
    )

    id: int=ormar.Integer(プライマリキー=True)
    title: str=ormar.String(max_length=200)
    カテゴリ:オプション[リスト[カテゴリ]]=ormar. ManyTomany(カテゴリ)

!!!ヒント多対多の関係の詳細については、多対多のセクションを参照してください

!!!tip ManyTomanyを使用すると、queryset-proxyを使用して関連するモデルをクエリできます。

1
`await post.categories.all()` だけでなく、`await category.posts.all()` を使用して、特定の投稿、カテゴリなどにのみ関連するデータを取得することができます。

フィールドを通して

ManyTomanyリレーションシップの一部として、フィルタリング、ソートなどに使用できる他のフィールドを含むパススルーモデルを定義できます。このように定義されたフィールドは、m2 mモデルの現在のクエリの反対側で公開されます。

したがって、モデルAからモデルBにクエリを実行すると、モデルBだけがthroughフィールドを公開します。関連する各モデルの一方通行のモデル/フィールドであるため、どちらが意味を持ちます。

 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
30
31
32
class Category(ormar. Model):
    ormar_config=ormar. OrmarConfig
        データベース=データベース、
        metadata=メタデータ,
        tablename="カテゴリ",
    )

    id=ormar. Integer(プライマリキー=True)
    name=ormar. String(max_length=40)

#スルーモデルに追加のフィールドを指定することができます。
class Post Category(ormar. Model):
    ormar_config=ormar. OrmarConfig
        データベース=データベース、
        metadata=メタデータ,
        tablename="post_x_カテゴリ",
    )

    id: int=ormar.Integer(プライマリキー=True)
    sort_order: int=ormar.Integer(nullable=True)
    param_name: str=ormar.String(default="Name",max_length=200)


class Post(ormar. Model):
    ormar_config=ormar. OrmarConfig
        データベース=データベース、
        metadata=メタデータ,
    )

    id: int=ormar.Integer(プライマリキー=True)
    title: str=ormar.String(max_length=200)
    カテゴリー=ormar. ManyTomany(カテゴリー、through=PostCategory)

!!!ヒント多対多のリレーションシップとフィールドの詳細については、多対多のセクションにアクセスしてください

!!!tip ManyTomanyを使用すると、queryset-proxyを使用して関連するモデルをクエリできます。

1
`await post.categories.all()` だけでなく、`await category.posts.all()` を使用して、特定の投稿、カテゴリなどにのみ関連するデータを取得することができます。

リレーションシップのデフォルトのソート順

デフォルトでは、リレーションシップはモデルのデフォルトのソート順序に従います。

!!!ヒントモデルの並べ替え順序の詳細については、ドキュメントのモデルセクションを参照してください

ただし、order_byパラメーターと関連_order_byパラメーターをリレーショナルに指定することで、クエリ中に関連するモデルがロードされる順序を変更できます。

リレーションシップでは、直接関連するモデル列、または複数対複数の列の場合はモデル列でのみソートできます {through_field_name}__{column_name}

構成例を次に示します。

 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
データベース=データベース。データベース(DATABASE_URL)
Metadata=sqlalchemy. MetaData()


base_ormar_config=ormar. OrmarConfig(ベースの設定
    データベース=データベース、
    metadata=メタデータ,
)


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

    id: int=ormar.Integer(プライマリキー=True)
    name: str=ormar.String(max_length=100)


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

    id: int=ormar.Integer(プライマリキー=True)
    著者:オプション[著者]=ormar. ForeignKey(
        著者、order_by=["name"]、関連するorder_by=["-year"]
    )
    title: str=ormar.String(max_length=100)
    year: int=ormar.Integer(nullable=True)
    ランキング: int=ormar.Integer(nullable=True)

今すぐ呼び出す:

await Author.objects.select_related("books").get() -書籍は書籍の年の降順で並べ替えられます

await Book.objects.select_related("author").all() -著者は著者名の昇順でソートされます

自己参照と遅延参照

自動リレーションシップを作成するか、少なくとも2つの異なるリレーションシップで互いに参照する2つのモデルを作成するには(裏面が自動的に登録されることに注意してください)、入力モジュールでForwardRefを使用する必要があります。

 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()

!!!ヒント自己参照と後回しの関係の詳細については、後回しのコメントセクションをご覧ください