...
 
Commits (2)
# -*- coding: utf-8 -*-
from ckeditor.widgets import CKEditorWidget
from django.contrib import admin
from django.forms import ModelForm
from django.core.validators import FileExtensionValidator
from django.forms import ModelForm, forms
from modeltranslation.admin import TabbedTranslationAdmin
from .models import *
from ..admin import FileInline, LinkInline
......@@ -15,6 +16,69 @@ class ClassificazioneEstesaAdminForm(ModelForm):
}
class ImportFocusForm(forms.Form):
file = forms.FileField(
validators=[FileExtensionValidator(allowed_extensions=['csv', 'zip'])],
label='File CSV o ZIP',
help_text='Carica un file CSV. Puoi caricare anche un file CSV zippato.'
)
def save(self):
import csv
import zipfile
from io import StringIO
from pathlib import Path
file = self.cleaned_data['file']
try:
if Path(file.name).suffix[1:].lower() == 'zip':
with zipfile.ZipFile(file) as zfile:
content = zfile.read(zfile.namelist().pop(0))
else:
content = file.read()
data = list(csv.DictReader(StringIO(content.decode('utf-8-sig')), delimiter=';'))
except zipfile.BadZipFile:
raise Exception('File ZIP non valido.')
except Exception:
raise Exception('File CSV non valido.')
else:
return self.process(data)
def process(self, data):
from django.db import connection
from django.db.models import Count
old_progettiwithfocus_pks = list(Progetto.objects.annotate(cnt=Count('focus')).filter(cnt__gt=0).values_list('pk', flat=True))
focus_slug2obj = {o.slug: o for o in Focus.objects.all()}
progetto_clp2pk = {x['codice_locale']: x['pk'] for x in Progetto.objects.filter(codice_locale__in=(r['COD_LOCALE_PROGETTO'] for r in data)).values('pk', 'codice_locale')}
ThroughModel = Focus.progetti.through
with connection.cursor() as cursor:
cursor.execute('TRUNCATE TABLE "{}" RESTART IDENTITY CASCADE;'.format(ThroughModel._meta.db_table))
objs = []
for row in data:
for focus_slug in row['OC_FOCUS'].replace('#', '').strip().split(' '):
if focus_slug not in focus_slug2obj:
focus_slug2obj[focus_slug] = Focus.objects.create(slug=focus_slug, nome=focus_slug.replace('_', ' ').capitalize())
obj = focus_slug2obj[focus_slug]
objs.append(ThroughModel(**{obj.progetti.source_field_name: obj, '{}_id'.format(obj.progetti.target_field_name): progetto_clp2pk[row['COD_LOCALE_PROGETTO']]}))
objs = ThroughModel.objects.bulk_create(objs)
new_progettiwithfocus_pks = list(progetto_clp2pk.values())
from .search_indexes import ProgettoIndex
index = ProgettoIndex()
index.get_backend().update(index, index.index_queryset().filter(pk__in=set(old_progettiwithfocus_pks + new_progettiwithfocus_pks)))
return len(objs)
class SoggettoAdmin(admin.ModelAdmin):
search_fields = ('denominazione',)
......@@ -84,6 +148,41 @@ class FocusAdmin(TabbedTranslationAdmin):
return self.readonly_fields + ('slug',)
return super().get_readonly_fields(request, obj)
def get_urls(self):
from django.conf.urls import url
urls = super().get_urls()
my_urls = [
url(r'^import/$', self.admin_site.admin_view(self.import_focus), name='{}_{}_import'.format(self.model._meta.app_label, self.model._meta.model_name)),
]
return my_urls + urls
def import_focus(self, request):
from django.shortcuts import redirect, render
form = ImportFocusForm(request.POST or None, request.FILES or None)
if request.method == 'POST':
if form.is_valid():
try:
counts = form.save()
except Exception as e:
from django.contrib import messages
self.message_user(request, 'Import non riuscito. {}'.format(e), level=messages.ERROR)
else:
self.message_user(request, 'Import completato con successo. Sono stati processati {} elementi'.format(counts))
return redirect('..')
opts = self.model._meta
context = {
**self.admin_site.each_context(request),
'title': 'Importa {}'.format(opts.verbose_name_plural),
'opts': opts,
'form': form,
}
return render(request, 'admin/{}/{}/import_form.html'.format(opts.app_label, opts.model_name), context)
class FonteAdmin(TabbedTranslationAdmin):
def get_readonly_fields(self, request, obj=None):
......
......@@ -622,19 +622,19 @@ class OpendataView(TemplateView):
section['data'] = [
{
'name': asterisk(format_lazy('{} - {}', _('Pubblica Amministrazione'), _('Entrate'))),
'file': self.get_complete_remotefile(cpt_path.format('PA_ENTRATE_2000-2017.zip')),
'file': self.get_complete_remotefile(cpt_path.format('PA_ENTRATE_2000-2018.zip')),
},
{
'name': asterisk(format_lazy('{} - {}', _('Pubblica Amministrazione'), _('Spese'))),
'file': self.get_complete_remotefile(cpt_path.format('PA_SPESE_2000-2017.zip')),
'file': self.get_complete_remotefile(cpt_path.format('PA_SPESE_2000-2018.zip')),
},
{
'name': asterisk(format_lazy('{} - {}', _('Settore Pubblico Allargato'), _('Entrate'))),
'file': self.get_complete_remotefile(cpt_path.format('SPA_ENTRATE_2000-2017.zip')),
'file': self.get_complete_remotefile(cpt_path.format('SPA_ENTRATE_2000-2018.zip')),
},
{
'name': asterisk(format_lazy('{} - {}', _('Settore Pubblico Allargato'), _('Spese'))),
'file': self.get_complete_remotefile(cpt_path.format('SPA_SPESE_2000-2017.zip')),
'file': self.get_complete_remotefile(cpt_path.format('SPA_SPESE_2000-2018.zip')),
},
{
'name': _('Metadati'),
......@@ -642,7 +642,7 @@ class OpendataView(TemplateView):
},
]
for file_info in section['data']:
file_info['file']['file_date'] = datetime.date(2019, 5, 31)
file_info['file']['file_date'] = datetime.date(2020, 6, 22)
subsection_keys = [key for key in opendata_sections if key.startswith('approfondimenti_') and key.endswith('_subsection')]
opendata_sections['approfondimenti_section']['subsections'] = [
......
This diff is collapsed.
{% extends 'admin/change_list.html' %}
{% load admin_urls %}
{% block object-tools-items %}
{% if user.is_superuser %}
<li>
<a href="{% url opts|admin_urlname:'import' %}">Importa {{ opts.verbose_name_plural }}</a>
</li>
{% endif %}
{{ block.super }}
{% endblock %}
{% extends 'admin/base_site.html' %}
{% load i18n admin_urls static %}
{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}">
<style>
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
{% endblock %}
{% block extrahead %}
{{ block.super }}
<script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/admin/jquery.blockUI.js' %}"></script>
<script>
$(document).ready(function() {
$('input[type="submit"]').on('click', function() {
$.blockUI({
message: ' ',
css: {
backgroundColor: 'transparent',
border: '8px solid #c4dce8',
borderTop: '8px solid #417690',
borderRadius: '50%',
width: '80px',
height: '80px',
left: '50%',
marginLeft: '-40px',
animation: 'spin 1s linear infinite'
}
})
});
});
</script>
{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>
&rsaquo; {{ title }}
</div>
{% endblock %}
{% block content %}
<div id="content-main">
<form enctype="multipart/form-data" action="." method="post" novalidate>
{% csrf_token %}
{% if form.errors %}
<p class="errornote">
{% if form.errors|length == 1 %}{% trans 'Please correct the error below.' %}{% else %}{% trans 'Please correct the errors below.' %}{% endif %}
</p>
{% endif %}
<fieldset class="module aligned">
<div class="form-row">
{% for field in form %}
<div class="fieldBox{% if field.errors %} errors{% endif %}">
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
{% if field.field.help_text %}
<div class="help">{{ field.field.help_text|safe }}</div>
{% endif %}
</div>
{% endfor %}
</div>
</fieldset>
<div class="submit-row">
<input type="submit" value="Importa" class="default">
</div>
</form>
</div>
{% endblock %}