diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-09-10 12:18:11 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-09-10 12:18:11 +0200 |
commit | 04bdc9d57ba7c2ece4c138c9dcb4072bb45a1608 (patch) | |
tree | ce7a3393b28403e6f053704ac6f8f0b9da028d07 | |
parent | 30d147bff5a2202f4d752c11596fd7f3f8939dd4 (diff) | |
download | Ishtar-04bdc9d57ba7c2ece4c138c9dcb4072bb45a1608.tar.bz2 Ishtar-04bdc9d57ba7c2ece4c138c9dcb4072bb45a1608.zip |
Serialization - restore: manage history (or not)
-rw-r--r-- | ishtar_common/admin.py | 20 | ||||
-rw-r--r-- | ishtar_common/lookups.py | 17 | ||||
-rw-r--r-- | ishtar_common/migrations/0105_auto_20190910_1100.py | 27 | ||||
-rw-r--r-- | ishtar_common/models.py | 9 | ||||
-rw-r--r-- | ishtar_common/serializers.py | 36 | ||||
-rw-r--r-- | ishtar_common/static/js/admin/archive_import.js | 10 | ||||
-rw-r--r-- | ishtar_common/tasks.py | 1 | ||||
-rw-r--r-- | ishtar_common/templates/admin/ishtar_common/importtask/change_form.html | 9 | ||||
-rw-r--r-- | ishtar_common/templates/admin/ishtar_common/importtask/change_list.html | 9 |
9 files changed, 120 insertions, 18 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py index 75e30a49c..691e68b26 100644 --- a/ishtar_common/admin.py +++ b/ishtar_common/admin.py @@ -1448,17 +1448,7 @@ admin_site.register(models.ExportTask, ExportTaskAdmin) """ -class Media: - js = ( - 'js/myscript.js', # project's static folder ( /static/js/myscript.js ) - ) -$(document).ready(function(){ - $('form').submit(function() { - var c = confirm("continue submitting ?"); - return c; - }); -}) """ @@ -1499,11 +1489,17 @@ launch_import_action.short_description = _("Launch import") class ImportTaskAdmin(admin.ModelAdmin): exclude = ('creation_date', 'launch_date', 'finished_date') - list_display = ['creation_date', "source", 'state', 'launch_date', - 'finished_date'] + list_display = ['creation_date', "source", 'state', "import_user", + 'launch_date', 'finished_date'] list_filter = ['state'] + form = make_ajax_form(models.ImportTask, {'import_user': 'user'}) actions = [launch_import_action] + class Media: + js = ( + 'js/admin/archive_import.js', + ) + admin_site.register(models.ImportTask, ImportTaskAdmin) diff --git a/ishtar_common/lookups.py b/ishtar_common/lookups.py index 495f69ddd..e2e9251e7 100644 --- a/ishtar_common/lookups.py +++ b/ishtar_common/lookups.py @@ -1,6 +1,7 @@ from ajax_select import register, LookupChannel as BaseLookupChannel from django.conf import settings +from django.contrib.auth.models import User from django.db.models import Q from ishtar_common import models @@ -42,6 +43,22 @@ class TownLookup(LookupChannel): return self.model.objects.filter(query).order_by('name')[:20] +@register('user') +class UserLookup(LookupChannel): + model = User + + def get_query(self, q, request): + query = Q() + for term in q.strip().split(' '): + query &= ( + Q(username__icontains=term) | + Q(first_name__icontains=term) | + Q(last_name__icontains=term) | + Q(email__icontains=term) + ) + return self.model.objects.filter(query).order_by('username')[:20] + + @register('organization') class OrganizationLookup(LookupChannel): model = models.Organization diff --git a/ishtar_common/migrations/0105_auto_20190910_1100.py b/ishtar_common/migrations/0105_auto_20190910_1100.py new file mode 100644 index 000000000..2e8ed2e62 --- /dev/null +++ b/ishtar_common/migrations/0105_auto_20190910_1100.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.18 on 2019-09-10 11:00 +from __future__ import unicode_literals + +from django.conf import settings +import django.contrib.gis.db.models.fields +import django.contrib.postgres.search +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import re + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('ishtar_common', '0104_regenerate_views'), + ] + + operations = [ + migrations.AddField( + model_name='importtask', + name='import_user', + field=models.ForeignKey(blank=True, help_text='If set the "Import user" will be the editor for last version. If the field is left empty no history will be recorded.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Import user'), + ), + ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 8da6c9bba..afd9994ca 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -5721,7 +5721,7 @@ class ExportTask(models.Model): class Meta: verbose_name = _("Archive - Export") - verbose_name_plural = _("Archive - Export") + verbose_name_plural = _("Archive - Exports") ordering = ['creation_date'] def __str__(self): @@ -5751,6 +5751,13 @@ class ImportTask(models.Model): creation_date = models.DateTimeField(default=datetime.datetime.now) launch_date = models.DateTimeField(null=True, blank=True) finished_date = models.DateTimeField(null=True, blank=True) + import_user = models.ForeignKey( + User, related_name='+', on_delete=models.SET_NULL, + verbose_name=_("Import user"), blank=True, null=True, + help_text=_("If set the \"Import user\" will be the editor for last " + "version. If the field is left empty no history will be " + "recorded.") + ) state = models.CharField(_("State"), max_length=2, choices=EXPORT_STATE, default='C') delete_before = models.BooleanField( diff --git a/ishtar_common/serializers.py b/ishtar_common/serializers.py index 99ec79933..6ff0ae9bb 100644 --- a/ishtar_common/serializers.py +++ b/ishtar_common/serializers.py @@ -276,7 +276,7 @@ def full_serialization(operation_queryset=None, site_queryset=None, return archive_name -def restore_serialized(archive_name, delete_existing=False): +def restore_serialized(archive_name, user=None, delete_existing=False): with zipfile.ZipFile(archive_name, "r") as zip_file: # check version info = json.loads(zip_file.read("info.json").decode("utf-8")) @@ -321,15 +321,41 @@ def restore_serialized(archive_name, delete_existing=False): if delete_existing: model.objects.all().delete() data = zip_file.read(json_filename).decode("utf-8") + # regenerate labels, add a new version, etc. + historized = hasattr(model, "history_modifier") and ( + hasattr(model, "history_creator")) + need_resave = hasattr(model, "CACHED_LABELS") or \ + hasattr(model, "cached_label") or \ + (user and historized) idx = -1 for idx, obj in enumerate(deserialize("json", data)): + extra_attrs = {} + if historized and not user: + keys = obj.object.natural_key() + old_obj = None + try: + old_obj = model.objects.get_by_natural_key( + *keys) + except model.DoesNotExist: + pass + if old_obj and (old_obj.history_creator or + old_obj.history_modifier): + extra_attrs = { + "history_modifier_id": + old_obj.history_modifier_id, + "history_creator_id": + old_obj.history_creator_id + } obj.save() - # force reindex - if hasattr(model, "CACHED_LABELS") or \ - hasattr(model, "cached_label"): + if need_resave or extra_attrs: obj = model.objects.get(id=obj.object.id) - obj.skip_history_when_saving = True + if user: + obj.history_modifier = user + else: + obj.skip_history_when_saving = True obj._no_move = True + for k in extra_attrs: + setattr(obj, k, extra_attrs[k]) obj.save() if idx >= 0: result.append((model.__name__, idx + 1)) diff --git a/ishtar_common/static/js/admin/archive_import.js b/ishtar_common/static/js/admin/archive_import.js new file mode 100644 index 000000000..2f407cd24 --- /dev/null +++ b/ishtar_common/static/js/admin/archive_import.js @@ -0,0 +1,10 @@ +ARCHIVE_IMPORT_SUBMIT_MESSAGE = "continue submitting ?"; + +django.jQuery(document).ready(function(){ + django.jQuery('form').submit(function() { + var action_value = django.jQuery("select[name='action']").val(); + if (action_value && action_value != "launch_import_action") return True; + var c = confirm(ARCHIVE_IMPORT_SUBMIT_MESSAGE); + return c; + }); +}) diff --git a/ishtar_common/tasks.py b/ishtar_common/tasks.py index 2b8806b32..1f95df392 100644 --- a/ishtar_common/tasks.py +++ b/ishtar_common/tasks.py @@ -51,6 +51,7 @@ def launch_import(import_task): import_task.save() restore_serialized(import_task.source.path, + import_task.import_user, delete_existing=import_task.delete_before) import_task.finished_date = datetime.datetime.now() import_task.state = 'F' diff --git a/ishtar_common/templates/admin/ishtar_common/importtask/change_form.html b/ishtar_common/templates/admin/ishtar_common/importtask/change_form.html new file mode 100644 index 000000000..781ac7b38 --- /dev/null +++ b/ishtar_common/templates/admin/ishtar_common/importtask/change_form.html @@ -0,0 +1,9 @@ +{% extends "admin/change_form.html" %} +{% load i18n %} + +{% block extrahead %} +{{ block.super }} +<script type="text/javascript"> +var ARCHIVE_IMPORT_SUBMIT_MESSAGE = "{% trans 'Are you sure you want to create/update an import task? If you are not cautious this operation may result in severe data loss.' %}"; +</script> +{% endblock %} diff --git a/ishtar_common/templates/admin/ishtar_common/importtask/change_list.html b/ishtar_common/templates/admin/ishtar_common/importtask/change_list.html new file mode 100644 index 000000000..795154b42 --- /dev/null +++ b/ishtar_common/templates/admin/ishtar_common/importtask/change_list.html @@ -0,0 +1,9 @@ +{% extends "admin/change_list.html" %} +{% load i18n %} + +{% block extrahead %} +{{ block.super }} +<script type="text/javascript"> +var ARCHIVE_IMPORT_SUBMIT_MESSAGE = "{% trans 'Are you sure you want to launch an import task? If you are not cautious this operation may result in severe data loss.' %}"; +</script> +{% endblock %} |