intercept save and delete
This commit is contained in:
parent
431372c4e4
commit
71789e7f41
6 changed files with 254 additions and 120 deletions
|
@ -1,8 +1,5 @@
|
|||
import datetime
|
||||
from collections import OrderedDict
|
||||
from contextlib import contextmanager
|
||||
from enum import StrEnum
|
||||
from typing import Literal, TypeAlias, Union, Annotated
|
||||
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
|
@ -15,92 +12,13 @@ from django.utils.timezone import make_naive
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ngettext_lazy
|
||||
from django_pydantic_field import SchemaField
|
||||
from pydantic.config import ConfigDict
|
||||
from pydantic.fields import Field
|
||||
from pydantic.types import Discriminator
|
||||
|
||||
from c3nav.api.schema import BaseSchema
|
||||
from c3nav.editor.changes import ChangeSetChanges
|
||||
from c3nav.editor.tasks import send_changeset_proposed_notification
|
||||
from c3nav.mapdata.models import LocationSlug, MapUpdate
|
||||
from c3nav.mapdata.models.locations import LocationRedirect
|
||||
from c3nav.mapdata.utils.cache.changes import changed_geometries
|
||||
|
||||
FieldValuesDict: TypeAlias = dict[int, str]
|
||||
ExistingOrCreatedID: TypeAlias = int # negative = temporary ID of created object
|
||||
|
||||
|
||||
class ObjectReferenceType(StrEnum):
|
||||
EXISTING = "existing"
|
||||
CREATED = "created"
|
||||
|
||||
|
||||
class ObjectReference(BaseSchema):
|
||||
model_config = ConfigDict(frozen=True)
|
||||
model: str
|
||||
id: ExistingOrCreatedID
|
||||
|
||||
|
||||
class BaseChange(BaseSchema):
|
||||
obj: ObjectReference
|
||||
datetime: datetime.datetime
|
||||
|
||||
|
||||
class CreateObjectChange(BaseChange):
|
||||
type: Literal["create"]
|
||||
fields: FieldValuesDict
|
||||
|
||||
|
||||
class UpdateObjectChange(BaseChange):
|
||||
type: Literal["update"]
|
||||
fields: FieldValuesDict
|
||||
|
||||
|
||||
class DeleteObjectChange(BaseChange):
|
||||
type: Literal["delete"]
|
||||
|
||||
|
||||
class AddManyToManyChange(BaseSchema):
|
||||
type: Literal["m2m_add"]
|
||||
field: str
|
||||
values: list[int]
|
||||
|
||||
|
||||
class RemoveManyToManyChange(BaseSchema):
|
||||
type: Literal["m2m_remove"]
|
||||
field: str
|
||||
values: list[int]
|
||||
|
||||
|
||||
class ClearManyToManyChange(BaseSchema):
|
||||
type: Literal["m2m_clear"]
|
||||
field: str
|
||||
|
||||
|
||||
ChangeSetChange = Annotated[
|
||||
Union[
|
||||
CreateObjectChange,
|
||||
UpdateObjectChange,
|
||||
DeleteObjectChange,
|
||||
AddManyToManyChange,
|
||||
RemoveManyToManyChange,
|
||||
ClearManyToManyChange,
|
||||
],
|
||||
Discriminator("type"),
|
||||
]
|
||||
|
||||
|
||||
class ChangeSetChanges(BaseSchema):
|
||||
prev_reprs: dict[ObjectReference, str] = {}
|
||||
prev_values: dict[ObjectReference, FieldValuesDict] = {}
|
||||
prev_m2m: dict[ObjectReference, dict[str, list[int]]] = {}
|
||||
changes: list[ChangeSetChange] = []
|
||||
|
||||
# maps negative IDs of created objects to the ID during the current transaction
|
||||
mapped_ids: Annotated[dict[ObjectReference, int], Field(exclude=True)] = {}
|
||||
|
||||
# maps IDs as used during the current transaction to the negative IDs
|
||||
reverse_mapped_ids: Annotated[dict[ObjectReference, int], Field(exclude=True)] = {}
|
||||
|
||||
|
||||
class ChangeSet(models.Model):
|
||||
STATES = (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue