Skip to content

Commit

Permalink
feat: model signal helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Nov 9, 2023
1 parent ca8ad4c commit 084f9ba
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
17 changes: 17 additions & 0 deletions codeforlife/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import typing as t

from django.db.models import Model as _Model


class Model(_Model):
"""A base class for all Django models.
Args:
_Model (django.db.models.Model): Django's model class.
"""

id: int
pk: int


AnyModel = t.TypeVar("AnyModel", bound=Model)
66 changes: 66 additions & 0 deletions codeforlife/models/signals.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,69 @@
import typing as t

from . import AnyModel

UpdateFields = t.Optional[t.FrozenSet[str]]


def check_post_save(
update_fields: UpdateFields,
expected_update_fields: UpdateFields,
):
"""https://docs.djangoproject.com/en/3.2/ref/signals/#post-save
Check if a model was updated with the expected fields.
Args:
update_fields: The fields that were updated.
expected_update_fields: A subset of the fields that were expected to be
updated. If no fields were expected to be updated, set to None.
Returns:
If the model instance was updated as expected.
"""

if expected_update_fields is None:
return update_fields is None
elif update_fields is None:
return False

return all(
update_field in update_fields for update_field in expected_update_fields
)


def check_pre_save(
update_fields: UpdateFields = None,
expected_update_fields: UpdateFields = None,
instance: t.Optional[AnyModel] = None,
created: bool = False,
created_only: bool = False,
):
"""https://docs.djangoproject.com/en/3.2/ref/signals/#pre-save
Check if a model was created or updated with the expected fields.
Args:
update_fields: The fields that were updated.
expected_update_fields: A subset of the fields that were expected to be
updated. If no fields were expected to be updated, set to None.
instance: Any model instance.
created: Check if the model was created.
created_only: Only check if the model was created.
Raises:
ValueError: If arg 'created' is True and arg 'instance' is None.
Returns:
If the model instance was created or updated as expected.
"""

if created:
if instance is None:
raise ValueError("Arg 'instance' cannot be None.")
if created_only:
return instance.pk is None
if instance.pk is None:
return True

return check_post_save(update_fields, expected_update_fields)

0 comments on commit 084f9ba

Please sign in to comment.