ohmyapi/docs/models.md
Brian Wiborg 91baf968d7
📝 Add mkdocs
2025-10-02 01:01:57 +02:00

3 KiB

Models

OhMyAPI uses Tortoise - an easy-to-use asyncio ORM (Object Relational Mapper) inspired by Django.

Models are exposed via a Python module named models in the app's directory. OhMyAPI auto-detects all models exposed this way. If the models module is a package, OhMyAPI will search through its submodules recursively.

Writing models

Your first simple model

from ohmyapi.db import Model, field


class Restaurant(Model):
    id: int = field.IntField(pk=True)
    name: str = field.CharField(max_length=255)
    description: str = field.TextField()
    location: str = field.CharField(max_length=255)

ForeignKeyRelations

You can define relationships between models.

from ohmyapi.db import Model, field

from decimal import Decimal


class Restaurant(Model):
    id: int = field.IntField(pk=True)
    name: str = field.CharField(max_length=255)
    description: str = field.TextField()
    location: str = field.CharField(max_length=255)


class Dish(Model):
    id: int = field.IntField(pk=True)
    restaurant: field.ForeignKeyRelation[Restaurant] = field.ForeignKeyField(
        "restaurant.Restaurant",
        related_name="dishes",
    )
    name: str = field.CharField(max_length=255)
    price: Decimal = field.DecimalField(max_digits=10, decimal_places=2)


class Order(Model):
    id: int = field.IntField(pk=True)
    restaurant: field.ForeignKeyRelation[Restaurant] = field.ForeignKeyField(
        'restaurant.Restaurant',
        related_name="dishes",
    )
    dishes: field.ManyToManyRelation[Dish] = field.ManyToManyField(
        "restaurant.Dish",
        relatated_name="orders",
        through="dishesordered",
    )

Pydantic Schema Validation

Each model has a builtin Schema class that provides easy access to Pydantic models for schema validation. Each model provides a default schema and a readonly schema, which you can obtain via the get method or by calling Schema() directly. The default schema contains the full collection of fields of the Tortoise model. The readonly schema excludes the primary-key field, as well as all readonly fields.

In [1]: from restaurant.models import Restaurant

In [2]: Restaurant.Schema.get()
Out[2]: tortoise.contrib.pydantic.creator.RestaurantSchema

In [3]: Restaurant.Schema.get(readonly=True)
Out[3]: tortoise.contrib.pydantic.creator.RestaurantSchemaReadonly

In [4]: data = {
   ...:     "name": "My Pizzeria",
   ...:     "description": "Awesome Pizza!",
   ...:     "location": "Berlin",
   ...: }

In [5]: Restaurant.Schema.get(readonly=True)(**data)
Out[5]: RestaurantSchemaReadonly(name='My Pizzeria', description='Awesome Pizza!', location='Berlin')

In [6]: Restaurant(**_.model_dump())
Out[6]: <Restaurant>

You can customize the fields to be include in the Pydantic schema:

class MyModel(Model):
    [...]

    class Schema:
        include: List[str] = []  # list of fields to include
        exclude: List[str] = []  # list of fields to exclude