コンテンツにスキップ

列のサブセットを選択

モデルで選択したカラムのみを選択するには、次の関数を使用します。

  • fields(columns: Union[List, str, set, dict]) -> QuerySet

  • exclude_fields(columns: Union[List, str, set, dict]) -> QuerySet

  • クエリセットエージェント

    • QuerysetProxy.fields(columns: Union[List, str, set, dict]) 方法
    • QuerysetProxy.exclude_fields(columns: Union[List, str, set, dict]) 方法

ドメイン

fields(columns: Union[List, str, set, dict]) -> QuerySet

field()を使用すると、モデル列のサブセットを選択してデータの負荷を制限できます。

(注)field()およびout of_field()は、マスターモデル(get、allなどの一般的なクエリ)と、選択されたモデルおよび事前に取得されたモデル(ネストされた表現を使用)の両方に適用されることに注意してください。

次のサンプルデータを示します。

 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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import asyncio

import databases
import ormar
import sqlalchemy
from examples import create_drop_database
from tests.settings import DATABASE_URL

base_ormar_config = ormar.OrmarConfig(
    database=databases.Database(DATABASE_URL, force_rollback=True),
    metadata=sqlalchemy.MetaData(),
)


class Company(ormar.Model):
    ormar_config = base_ormar_config.copy(tablename="companies")

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


class Car(ormar.Model):
    ormar_config = base_ormar_config.copy()

    id: int = ormar.Integer(primary_key=True)
    manufacturer = ormar.ForeignKey(Company)
    name: str = ormar.String(max_length=100)
    year: int = ormar.Integer(nullable=True)
    gearbox_type: str = ormar.String(max_length=20, nullable=True)
    gears: int = ormar.Integer(nullable=True)
    aircon_type: str = ormar.String(max_length=20, nullable=True)


@create_drop_database(base_config=base_ormar_config)
async def sample_data():
    # build some sample data
    toyota = await Company.objects.create(name="Toyota", founded=1937)
    await Car.objects.create(
        manufacturer=toyota,
        name="Corolla",
        year=2020,
        gearbox_type="Manual",
        gears=5,
        aircon_type="Manual",
    )
    await Car.objects.create(
        manufacturer=toyota,
        name="Yaris",
        year=2019,
        gearbox_type="Manual",
        gears=5,
        aircon_type="Manual",
    )
    await Car.objects.create(
        manufacturer=toyota,
        name="Supreme",
        year=2020,
        gearbox_type="Auto",
        gears=6,
        aircon_type="Auto",
    )


asyncio.run(sample_data())

str, List[str], Set[str] or dict にネストされた定義を指定するフィールドを1つ渡すことで選択できます。

関連するモデルを含めるには、シンボル {related_name}__{column}[__{optional_next} etc.] を使用します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
すべての車=await(
    車。オブジェクト
    . select_関連('メーカー')
    . field(['id','name','メーカー__name'])
    . all()
)
all_car内のcarについて:
    #除外された列はNoneを生成します
    assert all(getattr(car, x)is None for x in['year','gearbox_type','gears','aircon_type'])
    #関連するモデルに含まれる列が利用可能になり、pk列は常に含まれます。
    #フィールドリストに含めなくても
    アサートcar.manufacturer.name=='トヨタ'
    #ネストされた関連モデルでも-pkを除外することはできません-常に自動的に追加されます
    assert車。メーカー。設立されましたなし

field()は、選択するカラムを構築するために複数回呼び出すことができます。

関連するモデルをselect_ated()呼び出しに含める場合、これらのモデルの列をフィールドに指定しません

  • これらのネストされたモデルのすべてのフィールドのリストを意味します。

    すべての車=await( 車。オブジェクト . select_関連('メーカー') . field('id') . field(['name']) . all() )

    会社モデルのすべてのフィールドが選択されています。

    すべての車をアサート[0].manufacturer.name=='トヨタ' assert all_cars[0].メーカーが1937年に設立されました。

!!! 警告はValidationErrorを引き起こすため、強制フィールドを除外できません。除外するには、フィールドが空である必要があります。

1
2
`values()` メソッドは必須フィールドを除外するために使用できます。
`dict` として返されます。

この例では、必須のモデル列-製造元__名を除外することはできません。

1
2
3
4
5
6
7
待って(
    車。オブジェクト
    . select_関連('メーカー')
    . field(['id','name','メーカー__設立'])
    . all()
)
必要に応じてpydantic ValidationErrorcompany.nameます。

!!!tip Pk列は除外できません-明示的に含まれていなくても、常に自動的に追加されます。

また、辞書またはセットとして含めるフィールドを渡すことができます。

フィールドを辞書に含めるようにマークするには、その名前をキーとして使用し、値として省略記号を使用します。

ネストされたモデルをトラバースするには、ネストされたディクショナリを使用します。

ネストされた辞書ではなく、最後のレベルのフィールドを含めるには、コレクションを使用できます。

ネストされたモデル全体を含めるには、モデルに関連するフィールド名と省略記号を指定します。

同等の例を以下に示します。

 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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#1.上記の例のように
待って(
    車。オブジェクト
    . select_関連('メーカー')
    . field(['id','name','メーカー__name'])
    . all()
)

#2.必要に応じてフィールドをマークするには、省略記号を使用します。
待って(
    車。オブジェクト
    . select_関連('メーカー')
    . field({'id':.。。、
             'name':.。。、
             'メーカー':{
                 'name':.。。
                }
             })
    . all()
)

#3.ネストされたモデル全体を含めるには、楕円を使用します。
待って(
    車。オブジェクト
    . select_関連('メーカー')
    . field({'id':.。。、
             'name':.。。、
             'メーカー':.。。
             })
    . all()
)

#4.最後のネスティングレベルでフィールドを指定する
#上記の2と同等のセットを使用することもできます。
待って(
    車。オブジェクト
    . select_関連('メーカー')
    . field({'id':.。。、
             'name':.。。、
             'メーカー': {'name'}
             })
    . all()
)

#5.もちろんセットは複数のフィールドを持つことができます
待って(
    車。オブジェクト
    . select_関連('メーカー')
    . field({'id':.。。、
             'name':.。。、
             'メーカー': {'name', 'founded'}
             })
    . all()
)

#6。ネストされたすべてのフィールドを含めることができます。
#しかし、それは3に相当します。
待って(
    車。オブジェクト
    . select_関連('メーカー')
    . field({'id':.。。、
             'name':.。。、
             'メーカー': {'id', 'name', 'founded'}
             })
    . all()
)

!!!ローを返さないすべてのメソッドは、QuerySetインスタンスを明示的に返すため、それらをリンクできます

1
2
3
そのため、`filter()`、`select_related()`、`limit()`、`offset()` などの操作をチェーン化することができます。

のようなもの `Track.objects.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`

除外フィールド

exclude_fields(columns: Union[List, str, set, dict]) -> QuerySet

除_field()を使用すると、除外するモデル列のサブセットを選択して、データの読み込みを制限できます。

field()メソッドとは逆なので、利用可能なオプションについては上記のドキュメントを確認してください。

特に、階層全体からフィールドを除外するためのマスクとして、ネストされた辞書とコレクションが上記でどのように渡されるかを確認してください。

(注)field()およびout of_field()は、マスターモデル(get、allなどの一般的なクエリ)と、選択されたモデルおよび事前に取得されたモデル(ネストされた表現を使用)の両方に適用されることに注意してください。

以下にいくつかの簡単な例を見つけることができます。

  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
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import asyncio

import databases
import ormar
import sqlalchemy
from examples import create_drop_database
from tests.settings import DATABASE_URL

base_ormar_config = ormar.OrmarConfig(
    database=databases.Database(DATABASE_URL, force_rollback=True),
    metadata=sqlalchemy.MetaData(),
)


class Company(ormar.Model):
    ormar_config = base_ormar_config.copy(tablename="companies")

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


class Car(ormar.Model):
    ormar_config = base_ormar_config.copy()

    id: int = ormar.Integer(primary_key=True)
    manufacturer = ormar.ForeignKey(Company)
    name: str = ormar.String(max_length=100)
    year: int = ormar.Integer(nullable=True)
    gearbox_type: str = ormar.String(max_length=20, nullable=True)
    gears: int = ormar.Integer(nullable=True)
    aircon_type: str = ormar.String(max_length=20, nullable=True)


@create_drop_database(base_config=base_ormar_config)
async def sample_data():
    # build some sample data
    toyota = await Company.objects.create(name="Toyota", founded=1937)
    await Car.objects.create(
        manufacturer=toyota,
        name="Corolla",
        year=2020,
        gearbox_type="Manual",
        gears=5,
        aircon_type="Manual",
    )
    await Car.objects.create(
        manufacturer=toyota,
        name="Yaris",
        year=2019,
        gearbox_type="Manual",
        gears=5,
        aircon_type="Manual",
    )
    await Car.objects.create(
        manufacturer=toyota,
        name="Supreme",
        year=2020,
        gearbox_type="Auto",
        gears=6,
        aircon_type="Auto",
    )


asyncio.run(sample_data())


# select manufacturer but only name,
# to include related models use notation {model_name}__{column}
all_cars = await (
    Car.objects
    .select_related('manufacturer')
    .exclude_fields([
        'year',
        'gearbox_type',
        'gears',
        'aircon_type',
        'company__founded'
    ])
    .all()
)
for car in all_cars:
    # excluded columns will yield None
    assert all(getattr(car, x) is None
               for x in [
                   'year',
                   'gearbox_type',
                   'gears',
                   'aircon_type'
               ])
    # included column on related models will be available,
    # pk column is always included
    # even if you do not include it in fields list
    assert car.manufacturer.name == 'Toyota'
    # also in the nested related models,
    # you cannot exclude pk - it's always auto added
    assert car.manufacturer.founded is None

# fields() can be called several times,
# building up the columns to select
# models included in select_related 
# but with no columns in fields list implies all fields
all_cars = await (
    Car.objects
    .select_related('manufacturer')
    .exclude_fields('year')
    .exclude_fields(['gear', 'gearbox_type'])
    .all()
)
# all fields from company model are selected
assert all_cars[0].manufacturer.name == 'Toyota'
assert all_cars[0].manufacturer.founded == 1937

# cannot exclude mandatory model columns,
# company__name in this example - note usage of dict/set this time
await (
    Car.objects
    .select_related('manufacturer')
    .exclude_fields([{'company': {'name'}}])
    .all()
)
# will raise pydantic ValidationError as company.name is required

!!!警告はValidationErrorを引き起こすため、強制フィールドを除外できません。フィールドを除外するには、空である必要があります。

1
2
`values()` メソッドは必須フィールドを除外するために使用できます。
`dict` として返されます。

!!!ヒントPk列は除外できません-明示的に除外しても、常に自動的に追加されます。

!!!ローを返さないすべてのメソッドは、QuerySetインスタンスを明示的に返すため、それらをリンクできます

1
2
3
そのため、`filter()`、`select_related()`、`limit()`、`offset()` などの操作をチェーン化することができます。

のようなもの `Track.object.select_related("album").filter(album__name="Malibu").offset(1).limit(1).all()`

QuerysetProxyメソッド

関連するManyTomanyフィールドとReverseForeignKeyに直接アクセスする場合は、関連するモデルのリストを返します。

ただし、QuerySet APIのサブセットを公開しているため、親モデルから直接フィルタリング、作成、関連モデルの選択などを行うことができます。

ドメイン

上記のフィールドとまったく同じ機能ですが、関係の反対側にある関連オブジェクトから列を選択できます。

!!!ヒントQuerysetProxyの詳細については、querysetproxyセクションにアクセスしてください

除外フィールド

上記の「out put_field」関数と全く同じですが、関係の向こう側にある関連オブジェクトからカラムを選択することができます。

!!!ヒントQuerysetProxyの詳細については、querysetproxyセクションにアクセスしてください