import databases import sqlalchemy import ormar from tests.settings import DATABASE_URL database = databases.Database(DATABASE_URL, force_rollback=True) metadata = sqlalchemy.MetaData() class Company(ormar.Model): class Meta: tablename = "companies" metadata = metadata database = database id: int = ormar.Integer(primary_key=True) name: str = ormar.String(max_length=100) founded: int = ormar.Integer(nullable=True) class Car(ormar.Model): class Meta: tablename = "cars" metadata = metadata database = database 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) # 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') # 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 selected 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 fiels 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