diff --git a/src/c3nav/editor/operations.py b/src/c3nav/editor/operations.py index b06b2bfb..d5ffd57b 100644 --- a/src/c3nav/editor/operations.py +++ b/src/c3nav/editor/operations.py @@ -14,6 +14,7 @@ from pydantic.types import Discriminator from c3nav.api.schema import BaseSchema from c3nav.mapdata.fields import I18nField +from c3nav.mapdata.models import LocationSlug FieldValuesDict: TypeAlias = dict[str, Any] @@ -44,13 +45,28 @@ class CreateObjectOperation(BaseOperation): fields: FieldValuesDict def apply_create(self) -> Model: - instance = list(serializers.deserialize("json", json.dumps([{ + model = apps.get_model('mapdata', self.obj.model) + data = [] + if issubclass(model, LocationSlug): + data.append({ + "model": f"mapdata.locationslug", + "pk": self.obj.id, + "fields": { + "slug": self.fields.get("slug", None) + }, + }) + values = {key: val for key, val in self.fields.items() if key != "slug"} + else: + values = self.fields + data.append({ "model": f"mapdata.{self.obj.model}", "pk": self.obj.id, - "fields": self.fields, - }])))[0] - instance.save(save_m2m=False) - return instance.object + "fields": values, + }) + instances = list(serializers.deserialize("json", json.dumps(data))) + for instance in instances: + instance.save(save_m2m=False) + return instances[-1].object class UpdateObjectOperation(BaseOperation): @@ -66,13 +82,25 @@ class UpdateObjectOperation(BaseOperation): if val is not None} else: values[field_name] = value - instance = list(serializers.deserialize("json", json.dumps([{ + data = [] + if issubclass(model, LocationSlug) and "slug" in values: + data.append({ + "model": f"mapdata.locationslug", + "pk": self.obj.id, + "fields": { + "slug": values["slug"], + }, + }) + values = {key: val for key, val in values.items() if key != "slug"} + data.append({ "model": f"mapdata.{self.obj.model}", "pk": self.obj.id, "fields": values, - }])))[0] - instance.save(save_m2m=False) - return instance.object + }) + instances = list(serializers.deserialize("json", json.dumps(data))) + for instance in instances: + instance.save(save_m2m=False) + return instances[-1].object class DeleteObjectOperation(BaseOperation): diff --git a/src/c3nav/editor/overlay.py b/src/c3nav/editor/overlay.py index d22f4599..eeab3277 100644 --- a/src/c3nav/editor/overlay.py +++ b/src/c3nav/editor/overlay.py @@ -11,6 +11,7 @@ from django.db.models.fields.related import ManyToManyField from c3nav.editor.operations import DatabaseOperation, ObjectReference, FieldValuesDict, CreateObjectOperation, \ UpdateObjectOperation, DeleteObjectOperation, ClearManyToManyOperation, UpdateManyToManyOperation, CollectedChanges from c3nav.mapdata.fields import I18nField +from c3nav.mapdata.models import LocationSlug try: from asgiref.local import Local as LocalContext @@ -56,7 +57,10 @@ class DatabaseOverlayManager: @staticmethod def get_model_field_values(instance: Model) -> FieldValuesDict: - return json.loads(serializers.serialize("json", [instance]))[0]["fields"] + values = json.loads(serializers.serialize("json", [instance]))[0]["fields"] + if issubclass(instance._meta.model, LocationSlug): + values["slug"] = instance.slug + return values def get_ref_and_pre_change_values(self, instance: Model) -> tuple[ObjectReference, FieldValuesDict]: ref = ObjectReference.from_instance(instance)