Skip to content

mixin

django_spire.contrib.sync.django.mixin

SyncableMixin

Bases: Model

Source code in django_spire/contrib/sync/django/mixin.py
def __init__(self, *args: Any, **kwargs: Any) -> None:
    super().__init__(*args, **kwargs)

    self._tracker = FieldUpdateTracker()
    self._tracker.snapshot(self._get_field_values())

id = models.UUIDField(primary_key=True, default=(uuid.uuid4), editable=False) class-attribute instance-attribute

sync_field_timestamps = models.JSONField(default=dict, editable=False) class-attribute instance-attribute

sync_field_last_modified = models.BigIntegerField(default=0, editable=False, db_index=True) class-attribute instance-attribute

objects = SyncableQuerySet.as_manager() class-attribute instance-attribute

Meta

abstract = True class-attribute instance-attribute

save

Source code in django_spire/contrib/sync/django/mixin.py
def save(self, *args: Any, **kwargs: Any) -> None:
    if not _is_bypassed():
        dirty = self.get_dirty_fields()

        if dirty:
            now = self.get_clock().now()
            timestamps = dict(self.sync_field_timestamps)

            for field_name in dirty:
                timestamps[field_name] = now

            self.sync_field_timestamps = timestamps
            self.sync_field_last_modified = now

    super().save(*args, **kwargs)
    self._tracker.snapshot(self._get_field_values())

get_dirty_fields

Source code in django_spire/contrib/sync/django/mixin.py
def get_dirty_fields(self) -> set[str]:
    if self._state.adding:
        return set(self.get_syncable_field_names())

    return self._tracker.get_dirty(self._get_field_values())

refresh_from_db

Source code in django_spire/contrib/sync/django/mixin.py
def refresh_from_db(
    self, *args: Any, **kwargs: Any,
) -> None:
    super().refresh_from_db(*args, **kwargs)
    self._tracker.snapshot(self._get_field_values())

configure classmethod

Source code in django_spire/contrib/sync/django/mixin.py
@classmethod
def configure(cls, clock: HybridLogicalClock) -> None:
    cls._clock = clock

get_clock classmethod

Source code in django_spire/contrib/sync/django/mixin.py
@classmethod
def get_clock(cls) -> HybridLogicalClock:
    if cls._clock is None:
        message = (
            'SyncableMixin clock not configured. '
            'Call SyncableMixin.configure(clock) '
            'in AppConfig.ready().'
        )

        raise ClockNotConfiguredError(message)

    return cls._clock

get_syncable_field_names classmethod

Source code in django_spire/contrib/sync/django/mixin.py
@classmethod
def get_syncable_field_names(cls) -> list[str]:
    return sorted(
        field.name
        for field in cls._meta.concrete_fields
        if field.name not in cls._sync_exclude_fields
    )

get_syncable_m2m_names classmethod

Source code in django_spire/contrib/sync/django/mixin.py
@classmethod
def get_syncable_m2m_names(cls) -> list[str]:
    return sorted(
        field.name
        for field in cls._meta.many_to_many
    )