generate changed objects
This commit is contained in:
parent
8201f431b0
commit
bf14090010
2 changed files with 49 additions and 16 deletions
|
@ -54,7 +54,6 @@ class ChangeSet(models.Model):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.changed_objects = None
|
|
||||||
|
|
||||||
self.created_objects = {}
|
self.created_objects = {}
|
||||||
self.updated_existing = {}
|
self.updated_existing = {}
|
||||||
|
@ -234,7 +233,7 @@ class ChangeSet(models.Model):
|
||||||
return self.can_edit(request) and self.state == 'unproposed'
|
return self.can_edit(request) and self.state == 'unproposed'
|
||||||
|
|
||||||
def can_propose(self, request):
|
def can_propose(self, request):
|
||||||
return self.can_edit(request) and not self.proposed and self.changed_objects_count
|
return self.can_edit(request) and not self.proposed and self.changes.operations
|
||||||
|
|
||||||
def can_unpropose(self, request):
|
def can_unpropose(self, request):
|
||||||
return self.author_id == request.user.pk and self.state in ('proposed', 'reproposed')
|
return self.author_id == request.user.pk and self.state in ('proposed', 'reproposed')
|
||||||
|
@ -417,19 +416,7 @@ class ChangeSet(models.Model):
|
||||||
"""
|
"""
|
||||||
Get the number of changed objects.
|
Get the number of changed objects.
|
||||||
"""
|
"""
|
||||||
self.fill_changes_cache()
|
return len(self.changes.changed_objects)
|
||||||
count = 0
|
|
||||||
changed_locationslug_pks = set()
|
|
||||||
for model, objects in self.changed_objects.items():
|
|
||||||
if issubclass(model, LocationSlug):
|
|
||||||
if model == LocationRedirect:
|
|
||||||
continue
|
|
||||||
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.obj.target_id
|
|
||||||
for obj in self.changed_objects.get(LocationRedirect, {}).values()) - changed_locationslug_pks)
|
|
||||||
return count
|
|
||||||
|
|
||||||
def get_changed_objects_by_model(self, model):
|
def get_changed_objects_by_model(self, model):
|
||||||
if isinstance(model, str):
|
if isinstance(model, str):
|
||||||
|
@ -446,7 +433,6 @@ class ChangeSet(models.Model):
|
||||||
if self.direct_editing:
|
if self.direct_editing:
|
||||||
return _('Direct editing active')
|
return _('Direct editing active')
|
||||||
return _('No objects changed')
|
return _('No objects changed')
|
||||||
return 'something was changed' # todo: make this nice again
|
|
||||||
return (ngettext_lazy('%(num)d object changed', '%(num)d objects changed', 'num') %
|
return (ngettext_lazy('%(num)d object changed', '%(num)d objects changed', 'num') %
|
||||||
{'num': self.changed_objects_count})
|
{'num': self.changed_objects_count})
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,21 @@ DatabaseOperation = Annotated[
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ChangedManyToMany(BaseSchema):
|
||||||
|
cleared: bool = False
|
||||||
|
added: list[str] = []
|
||||||
|
removed: list[str] = []
|
||||||
|
|
||||||
|
|
||||||
|
class ChangedObject(BaseSchema):
|
||||||
|
obj: ObjectReference
|
||||||
|
repr: str
|
||||||
|
created: bool = False
|
||||||
|
deleted: bool = False
|
||||||
|
fields: FieldValuesDict = {}
|
||||||
|
m2m_changes: dict[str, ChangedManyToMany] = {}
|
||||||
|
|
||||||
|
|
||||||
class CollectedChanges(BaseSchema):
|
class CollectedChanges(BaseSchema):
|
||||||
prev_reprs: dict[str, dict[int, str]] = {}
|
prev_reprs: dict[str, dict[int, str]] = {}
|
||||||
prev_values: dict[str, dict[int, FieldValuesDict]] = {}
|
prev_values: dict[str, dict[int, FieldValuesDict]] = {}
|
||||||
|
@ -128,6 +143,38 @@ class CollectedChanges(BaseSchema):
|
||||||
|
|
||||||
return CollectedChangesPrefetch(changes=self, instances=instances)
|
return CollectedChangesPrefetch(changes=self, instances=instances)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def changed_objects(self) -> list[ChangedObject]:
|
||||||
|
objects = {}
|
||||||
|
for operation in self.operations:
|
||||||
|
changed_object = objects.get(operation.obj, None)
|
||||||
|
if changed_object is None:
|
||||||
|
changed_object = ChangedObject(obj=operation.obj,
|
||||||
|
repr=self.prev_reprs[operation.obj.model][operation.obj.id])
|
||||||
|
objects[operation.obj] = changed_object
|
||||||
|
if isinstance(operation, CreateObjectOperation):
|
||||||
|
changed_object.created = True
|
||||||
|
changed_object.fields.update(operation.fields)
|
||||||
|
elif isinstance(operation, UpdateObjectOperation):
|
||||||
|
changed_object.fields.update(operation.fields)
|
||||||
|
elif isinstance(operation, DeleteObjectOperation):
|
||||||
|
changed_object.deleted = False
|
||||||
|
else:
|
||||||
|
changed_m2m = changed_object.m2m_changes.get(operation.field, None)
|
||||||
|
if changed_m2m is None:
|
||||||
|
changed_m2m = ChangedManyToMany()
|
||||||
|
changed_object.m2m_changes[operation.field] = changed_m2m
|
||||||
|
if isinstance(operation, ClearManyToManyOperation):
|
||||||
|
changed_m2m.cleared = True
|
||||||
|
changed_m2m.added = []
|
||||||
|
changed_m2m.removed = []
|
||||||
|
else:
|
||||||
|
changed_m2m.added = sorted((set(changed_m2m.added) | operation.add_values)
|
||||||
|
- operation.remove_values)
|
||||||
|
changed_m2m.removed = sorted((set(changed_m2m.removed) - operation.add_values)
|
||||||
|
| operation.remove_values)
|
||||||
|
return list(objects.values())
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class CollectedChangesPrefetch:
|
class CollectedChangesPrefetch:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue