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 %}  | 
