diff --git a/apis_core/apis_entities/edit_generic.py b/apis_core/apis_entities/edit_generic.py index 77c5477b1..3b68638a1 100644 --- a/apis_core/apis_entities/edit_generic.py +++ b/apis_core/apis_entities/edit_generic.py @@ -1,4 +1,5 @@ import importlib +import json from django.conf import settings from django.contrib.auth.decorators import login_required @@ -14,6 +15,7 @@ from django.views.generic import DeleteView from django_tables2 import RequestConfig from reversion.models import Version +from reversion import set_comment as reversion_set_comment, create_revision from apis_core.apis_labels.models import Label from apis_core.apis_metainfo.models import Uri @@ -139,6 +141,16 @@ def post(self, request, *args, **kwargs): form = form(request.POST, instance=self.instance) if form.is_valid(): entity_2 = form.save() + comment = [ + { + "changed": { + "name": str(entity_2._meta.verbose_name), + "object": str(entity_2), + "fields": form.changed_data, + } + } + ] + reversion_set_comment(json.dumps(comment)) return redirect( reverse( "apis:apis_entities:generic_entities_edit_view", @@ -186,6 +198,15 @@ def post(self, request, *args, **kwargs): form = form(request.POST) if form.is_valid(): entity_2 = form.save() + comment = [ + { + "added": { + "name": str(entity_2._meta.verbose_name), + "object": str(entity_2), + } + } + ] + reversion_set_comment(json.dumps(comment)) return redirect( reverse( "apis:apis_entities:generic_entities_detail_view", @@ -255,6 +276,7 @@ class GenericEntitiesDeleteView(EntityInstanceMixin, DeleteView): ) def dispatch(self, request, *args, **kwargs): + self.success_url = reverse( "apis_core:apis_entities:generic_entities_list", kwargs={"entity": self.entity}, @@ -265,9 +287,21 @@ def dispatch(self, request, *args, **kwargs): @method_decorator(login_required, name="dispatch") class GenericEntitiesDuplicateView(EntityInstanceMixin, View): def get(self, request, *args, **kwargs): - source_obj = get_object_or_404(self.entity_model, pk=self.pk) + with create_revision(): + source_obj = get_object_or_404(self.entity_model, pk=self.pk) + + newobj = source_obj.duplicate() - newobj = source_obj.duplicate() + comment = [ + { + "added": { + "name": str(newobj._meta.verbose_name), + "object": str(newobj), + "duplicate_from": str(source_obj), + } + } + ] + reversion_set_comment(json.dumps(comment)) return redirect( reverse( diff --git a/apis_core/apis_entities/models.py b/apis_core/apis_entities/models.py index 6ba282177..fe5f3a86e 100644 --- a/apis_core/apis_entities/models.py +++ b/apis_core/apis_entities/models.py @@ -1,6 +1,7 @@ import re import re import unicodedata +import json from django.contrib.contenttypes.models import ContentType from django.apps import apps @@ -13,6 +14,7 @@ from django.urls import reverse from model_utils.managers import InheritanceManager from django.db.models.query import QuerySet +from reversion import set_comment as reversion_set_comment from apis_core.utils import caching from apis_core.utils import DateParser @@ -322,6 +324,8 @@ def merge_with(self, entities): origin = self.__class__ signals.pre_merge_with.send(sender=origin, instance=self, entities=entities) + reversion_comments = [] + # TODO: check if these imports can be put to top of module without # causing circular import issues. from apis_core.apis_labels.models import Label @@ -361,6 +365,18 @@ def merge_with(self, entities): TempTriple.objects.filter(obj__id=ent.id).update(obj=self) TempTriple.objects.filter(subj__id=ent.id).update(subj=self) + reversion_comments.append( + { + "changed": { + "name": str(self._meta.verbose_name), + "object": str(self), + "merged_from": str(ent), + } + } + ) + + reversion_set_comment(json.dumps(reversion_comments)) + for ent in entities: self.merge_fields(ent) diff --git a/apis_core/apis_entities/templates/apis_entities/detail_views/detail_generic.html b/apis_core/apis_entities/templates/apis_entities/detail_views/detail_generic.html index 121686a83..52a9ea794 100644 --- a/apis_core/apis_entities/templates/apis_entities/detail_views/detail_generic.html +++ b/apis_core/apis_entities/templates/apis_entities/detail_views/detail_generic.html @@ -70,6 +70,12 @@

content_copy {% endif %} + + | + + history + {% endif %} {% endblock object-actions %} diff --git a/apis_core/core/templates/reversion/version_list.html b/apis_core/core/templates/reversion/version_list.html new file mode 100644 index 000000000..e152bcbee --- /dev/null +++ b/apis_core/core/templates/reversion/version_list.html @@ -0,0 +1,9 @@ +{% extends basetemplate %} + +{% block content %} + +{% endblock content %} diff --git a/apis_core/core/views.py b/apis_core/core/views.py new file mode 100644 index 000000000..6f8dce065 --- /dev/null +++ b/apis_core/core/views.py @@ -0,0 +1,21 @@ +from django.views.generic.list import ListView +from django.contrib.contenttypes.models import ContentType +from reversion.models import Revision, Version + + +class Versions(ListView): + paginate_by = 100 + model = Version + instance = None + + def dispatch(self, request, *args, **kwargs): + if content_type := kwargs.get("content_type"): + contenttype = ContentType.objects.get_for_id(content_type) + if object_id := kwargs.get("object_id"): + self.instance = contenttype.model_class().objects.get(pk=object_id) + return super().dispatch(request, *args, **kwargs) + + def get_queryset(self): + if self.instance: + return Version.objects.get_for_object(self.instance) + return Version.objects.all() diff --git a/apis_core/urls.py b/apis_core/urls.py index 13402e075..15ef77d02 100644 --- a/apis_core/urls.py +++ b/apis_core/urls.py @@ -10,6 +10,8 @@ from apis_core.api_routers import load_additional_serializers from apis_core.api_routers import views +from apis_core.core.views import Versions + # from apis_core.apis_entities.api_views import ( # NetJsonViewSet, # PlaceGeoJsonViewSet, @@ -185,6 +187,12 @@ def build_apis_mock_request(method, path, view, original_request, **kwargs): ), # url(r'^docs/', include('sphinxdoc.urls')), # url(r'^accounts/', include('registration.backends.simple.urls')), + path("reversion/versions/", Versions.as_view(), name="versions"), + path( + "reversion/versions//", + Versions.as_view(), + name="versions", + ), ] if "apis_highlighter" in settings.INSTALLED_APPS: