intercept save and delete

This commit is contained in:
Laura Klünder 2024-08-22 22:49:07 +02:00
parent 431372c4e4
commit 71789e7f41
6 changed files with 254 additions and 120 deletions

View file

@ -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 = (