diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-02-12 17:55:23 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-02-12 17:55:23 +0100 |
commit | bb8e1f0d4b7b6243fa60f1ec3280165fdc297a0f (patch) | |
tree | ab0d2a77067acb7dff9c8912dbe2db0a25cf578f /ishtar_common/admin.py | |
parent | f0c15964ee7b5ecfcbe5bfa8fa1def673a0712cf (diff) | |
download | Ishtar-bb8e1f0d4b7b6243fa60f1ec3280165fdc297a0f.tar.bz2 Ishtar-bb8e1f0d4b7b6243fa60f1ec3280165fdc297a0f.zip |
Admin: manage import form exported models
Diffstat (limited to 'ishtar_common/admin.py')
-rw-r--r-- | ishtar_common/admin.py | 167 |
1 files changed, 127 insertions, 40 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py index a0224d4cd..8070b5180 100644 --- a/ishtar_common/admin.py +++ b/ishtar_common/admin.py @@ -24,6 +24,7 @@ from ajax_select.fields import AutoCompleteSelectField, \ AutoCompleteSelectMultipleField from django.conf import settings +from django.conf.urls import url from django.contrib import admin from django.contrib.auth.admin import GroupAdmin, UserAdmin from django.contrib.auth.models import Group, User @@ -32,6 +33,9 @@ from django.contrib.sites.admin import SiteAdmin from django.contrib.sites.models import Site from django.contrib.gis.forms import PointField, OSMWidget, MultiPolygonField from django.core.cache import cache +from django.core.urlresolvers import reverse +from django.db.models.fields import BooleanField, IntegerField, FloatField +from django.db.models.fields.related import ForeignKey from django.forms import BaseInlineFormSet from django.http import HttpResponseRedirect, HttpResponse from django.shortcuts import render @@ -60,41 +64,11 @@ ISHTAR_FORMS = [common_forms, file_pdl_forms, file_forms, operation_forms, class ImportGenericForm(forms.Form): - _selected_action = forms.CharField(widget=forms.MultipleHiddenInput) csv_file = forms.FileField( - "CSV file", help_text="Only unicode encoding is managed - convert your" - " file first") - - -def gen_import_generic(self, request, queryset): - form = None - - if 'apply' in request.POST: - form = ImportGenericForm(request.POST, request.FILES) - - if form.is_valid(): - csv_file = request.FILES['csv_file'] - reader = csv.reader(csv_file) - idx = 0 - for row in reader: - slug = slugify(row[0]) - if self.model.objects.filter(txt_idx=slug).count(): - continue - obj, c = self.model.objects.get_or_create( - label=row[0], txt_idx=slug) - if c: - idx += 1 - self.message_user(request, "Successfully added %d new items." % ( - idx)) - return HttpResponseRedirect(request.get_full_path()) - if not form: - form = ImportGenericForm( - initial={'_selected_action': - request.POST.getlist(admin.ACTION_CHECKBOX_NAME)}) - return render(request, 'admin/import_from_csv.html', {'csv_form': form}) - - -gen_import_generic.short_description = "Import from a CSV file" + _(u"CSV file"), + help_text=_(u"Only unicode encoding is managed - convert your" + u" file first") + ) def export_as_csv_action(description=_(u"Export selected as CSV file"), @@ -125,10 +99,21 @@ def export_as_csv_action(description=_(u"Export selected as CSV file"), writer = csv.writer(response) if header: writer.writerow(list(field_names)) - for obj in queryset: - writer.writerow([ - unicode(getattr(obj, field)).encode("utf-8", "replace") - for field in field_names]) + for obj in queryset.order_by('pk'): + row = [] + for field in field_names: + value = getattr(obj, field) + if hasattr(value, 'txt_idx'): + value = getattr(value, 'txt_idx') + elif hasattr(value, 'slug'): + value = getattr(value, 'txt_idx') + elif value is None: + value = "" + else: + value = unicode(value).encode("utf-8", "replace") + row.append(value) + + writer.writerow(row) return response export_as_csv.short_description = description return export_as_csv @@ -272,9 +257,111 @@ admin_site.register(models.GlobalVar, GlobalVarAdmin) class GeneralTypeAdmin(admin.ModelAdmin): list_display = ['label', 'txt_idx', 'available', 'comment'] search_fields = ('label', 'txt_idx', 'comment',) - actions = ['import_generic', export_as_csv_action()] + actions = [export_as_csv_action()] prepopulated_fields = {"txt_idx": ("label",)} - import_generic = gen_import_generic + change_list_template = "admin/gen_change_list.html" + + def get_urls(self): + urls = super(GeneralTypeAdmin, self).get_urls() + my_urls = [ + url(r'^import-from-csv/$', self.import_generic), + ] + return my_urls + urls + + def import_generic(self, request): + form = None + + if 'apply' in request.POST: + form = ImportGenericForm(request.POST, request.FILES) + if form.is_valid(): + csv_file = request.FILES['csv_file'] + reader = csv.DictReader(csv_file) + created, updated, missing_parent = 0, 0, [] + for row in reader: + if 'slug' in row: + slug_col = 'slug' + elif 'txt_idx' in row: + slug_col = 'txt_idx' + else: + self.message_user( + request, + unicode(_(u"The CSV file should at least have a " + u"slug/txt_idx column"))) + return + slug = row.pop(slug_col) + if 'id' in row: + row.pop('id') + if 'pk' in row: + row.pop('pk') + for k in row.keys(): + value = row[k] + if value == 'None': + value = '' + field = self.model._meta.get_field(k) + if isinstance(field, IntegerField): + if not value: + value = None + else: + value = int(value) + elif isinstance(field, FloatField): + if not value: + value = None + else: + value = value(value) + elif isinstance(field, BooleanField): + if value in ('true', 'True', '1'): + value = True + elif value in ('false', 'False', '0'): + value = False + else: + value = None + elif isinstance(field, ForeignKey): + if not value: + value = None + else: + model = field.rel.to + try: + value = model.objects.get( + **{slug_col: value} + ) + except model.DoesNotExist: + missing_parent.append(row.pop(k)) + continue + row[k] = value + values = { + slug_col: slug, + 'defaults': row + } + obj, c = self.model.objects.get_or_create( + **values) + if not c: + updated += 1 + self.model.objects.filter(pk=obj.pk).update(**row) + else: + created += 1 + if created: + self.message_user( + request, + unicode(_(u"%d item(s) created.")) % created) + if updated: + self.message_user( + request, + unicode(_(u"%d item(s) updated.")) % updated) + if missing_parent: + self.message_user( + request, + unicode(_(u"Theses parents are missing: {}")).format( + u" ; ".join(missing_parent) + )) + url = reverse( + 'admin:%s_%s_changelist' % ( + self.model._meta.app_label, self.model._meta.model_name) + ) + return HttpResponseRedirect(url) + if not form: + form = ImportGenericForm() + return render(request, 'admin/import_from_csv.html', {'csv_form': form}) + general_models = [models.OrganizationType, models.SourceType, models.AuthorType, models.TitleType, models.Format, |