diff --git a/src/c3nav/editor/models/changeset.py b/src/c3nav/editor/models/changeset.py index b3d31d3d..8aadcf44 100644 --- a/src/c3nav/editor/models/changeset.py +++ b/src/c3nav/editor/models/changeset.py @@ -305,7 +305,10 @@ class ChangeSet(models.Model): existing_pks = pks - created_pks model_objects = {} if existing_pks: - qs = model.objects.filter(pk__in=existing_pks) + qs = model.objects + if model is LocationSlug: + qs = qs.select_related_target() + qs = qs.filter(pk__in=existing_pks) for prefetch in prefetch_related: try: model._meta.get_field(prefetch) @@ -313,7 +316,7 @@ class ChangeSet(models.Model): pass else: qs = qs.prefetch_related(prefetch) - for obj in model.objects.filter(pk__in=existing_pks): + for obj in qs: if model == LocationSlug: obj = obj.get_child() model_objects[obj.pk] = obj @@ -326,6 +329,11 @@ class ChangeSet(models.Model): for pk, obj in objects.get(LocationSlug, {}).items(): objects.setdefault(obj.__class__, {})[pk] = obj + for pk, obj in objects.get(LocationRedirect, {}).items(): + target = obj.target.get_child() + objects.setdefault(LocationSlug, {})[target.pk] = target + objects.setdefault(target.__class__, {})[target.pk] = target + return objects def get_changed_values(self, model: models.Model, name: str) -> tuple: @@ -645,7 +653,7 @@ class ChangeSet(models.Model): changed_locationslug_pks.update(objects.keys()) count += sum(1 for obj in objects.values() if not obj.is_created or not obj.deleted) - count += len(set(obj.updated_fields['target'] + count += len(set(obj.obj.target_id for obj in self.changed_objects.get(LocationRedirect, {}).values()) - changed_locationslug_pks) return count diff --git a/src/c3nav/editor/views/changes.py b/src/c3nav/editor/views/changes.py index 9571e663..d7586eab 100644 --- a/src/c3nav/editor/views/changes.py +++ b/src/c3nav/editor/views/changes.py @@ -193,9 +193,9 @@ def changeset_detail(request, pk): for changed_object in changeset.changed_objects.get(LocationRedirect, {}).values(): if changed_object.is_created == changed_object.deleted: continue - values = changed_object.updated_fields + obj = objects[LocationRedirect][changed_object.obj_pk] redirect_list = (removed_redirects if changed_object.deleted else added_redirects) - redirect_list.setdefault(values['target'], []).append(values['slug']) + redirect_list.setdefault(obj.target_id, []).append(obj.slug) redirect_changed_objects = [] diff --git a/src/c3nav/mapdata/models/locations.py b/src/c3nav/mapdata/models/locations.py index 6526ff7f..6e0b490f 100644 --- a/src/c3nav/mapdata/models/locations.py +++ b/src/c3nav/mapdata/models/locations.py @@ -17,6 +17,14 @@ class LocationSlugManager(models.Manager): for model in get_submodels(Location)+[LocationRedirect])) return result + def select_related_target(self): + if self.model != LocationSlug: + raise TypeError + qs = self.get_queryset() + qs = qs.select_related('redirect__target', *('redirect__target__'+model._meta.default_related_name + for model in get_submodels(Location) + [LocationRedirect])) + return qs + class LocationSlug(SerializableMixin, models.Model): LOCATION_TYPE_CODES = {