tortoise-orm icon indicating copy to clipboard operation
tortoise-orm copied to clipboard

Signals not working within classes

Open Kyzegs opened this issue 4 years ago • 1 comments

Describe the bug You're unable to use signal decorators within classes.

To Reproduce

from tortoise.backends.base.client import BaseDBAsyncClient
from tortoise.signals import post_save
from typing import List, Optional, Type

from .models import Model


class Example:
    @post_save(Model)
    async def signal_post_save(
        self,
        sender: Type[Model],
        instance: Model,
        created: bool,
        using_db: Optional[BaseDBAsyncClient],
        update_fields: List[str],
    ) -> None:
        print(sender, instance, using_db, created, update_fields)

Kyzegs avatar Feb 05 '22 22:02 Kyzegs

The post_save decorator takes the model class you want to define the signal for as an argument. This cannot be accessed during the class definition. You could get tricky with partial functions and own custom decorators to get this to work at runtime, or you could simply call the signal-creator after the class definition:

from tortoise.backends.base.client import BaseDBAsyncClient
from tortoise.signals import post_save, Signals
from typing import List, Optional, Type

class Example:

    async def signal_post_save(
        self,
        sender: Type[Model],
        instance: Model,
        created: bool,
        using_db: Optional[BaseDBAsyncClient],
        update_fields: List[str],
    ) -> None:
        print(sender, instance, using_db, created, update_fields)

Example.register_listener(Signals.post_save, Example.signal_post_save)

Although far from elegant, you get to keep the signal definition in the class.

teschmitt avatar Feb 14 '22 11:02 teschmitt