def form_valid(self, form): current_perimeter = self.get_object() perimeter_type = form.cleaned_data['perimeter_type'] if perimeter_type == 'city_code': # Fetch the list of commune perimeters from the uploaded file # The list should be error-free (cleaned in PerimeterUploadForm) city_codes = extract_perimeters_from_file( form.cleaned_data['city_code_list']) attach_perimeters(current_perimeter, city_codes) elif perimeter_type == 'epci_name': # Fetch the list of EPCI perimeters from the uploaded file # The list should be error-free (cleaned in PerimeterUploadForm) epci_names = extract_perimeters_from_file( form.cleaned_data['epci_name_list']) attach_epci_perimeters(current_perimeter, epci_names) msg = format_html(_('The {name} “{obj}” was changed successfully.'), name=_('Perimeter'), obj=format_html('<a href="{obj_url}">{obj_name}</a>', obj_url=reverse( 'admin:geofr_perimeter_change', args=[current_perimeter.id]), obj_name=current_perimeter)) self.messages.success(msg) return super().form_valid(form)
def test_attach_perimeters_cleans_old_data(perimeters): """Attaching perimeters removes all other attachments.""" adhoc = PerimeterFactory(name='Communes littorales', scale=Perimeter.TYPES.adhoc) perimeters['rodez'].contained_in.add(adhoc) attach_perimeters(adhoc, ['34333', '97209']) # Vic-la-gardiole, Fort-de-France assert adhoc not in perimeters['rodez'].contained_in.all()
def form_valid(self, form): current_perimeter = self.get_object() add_perimeters = form.cleaned_data['add_perimeters'] rm_perimeters = form.cleaned_data['rm_perimeters'] city_codes = combine_perimeters(add_perimeters, rm_perimeters) attach_perimeters(current_perimeter, city_codes) msg = _('We successfully configured the perimeter.') self.messages.success(msg) return super().form_valid(form)
def handle(self, *args, **options): scots = {} nb_created = 0 nb_updated = 0 # TODO Remote all "contained in" scot perimeter links # Import data from csv file csv_path = os.path.abspath(options['csv_file'][0]) with open(csv_path) as csv_file: reader = csv.reader(csv_file, delimiter=',') for row in reader: scot_id = row[0] scot_name = row[1] insee_code = row[2] if scot_id not in scots: scots[scot_id] = { 'name': scot_name, 'communes': [] } scots[scot_id]['communes'].append(insee_code) for scot_id in scots.keys(): # id is just an integer, we use a custom code to make it unique scot_code = 'SCOT-{}'.format(scot_id) scot_name = scots[scot_id]['name'] # Create the scot perimeter scot, created = Perimeter.objects.update_or_create( scale=Perimeter.TYPES.adhoc, code=scot_code, defaults={ 'name': scot_name, }) if created: nb_created += 1 else: nb_updated += 1 # Link the scot with the related communes codes = scots[scot_id]['communes'] attach_perimeters(scot, codes) self.stdout.write(self.style.SUCCESS( '%d scots created, %d updated.' % (nb_created, nb_updated)))
def test_attach_perimeters(perimeters): """Attaching perimeters works as expected.""" adhoc = PerimeterFactory(name='Communes littorales', scale=Perimeter.TYPES.adhoc) attach_perimeters(adhoc, ['34333', '97209']) # Vic-la-gardiole, Fort-de-France assert adhoc in perimeters['vic'].contained_in.all() assert adhoc in perimeters['herault'].contained_in.all() assert adhoc in perimeters['occitanie'].contained_in.all() assert adhoc in perimeters['métropole'].contained_in.all() assert adhoc in perimeters['outre-mer'].contained_in.all() # Make sure perimeter does not contain itself assert adhoc not in adhoc.contained_in.all() # Make sure france and europe are not contained in the adhoc perimeter assert adhoc not in perimeters['france'].contained_in.all() assert adhoc not in perimeters['europe'].contained_in.all()
def handle(self, *args, **options): # Create basin perimeters basin_to_commune = {} nb_created = 0 nb_updated = 0 for code, basin_name in DRAINAGE_BASINS.items(): basin, created = Perimeter.objects.get_or_create( scale=Perimeter.TYPES.basin, code=code, name=basin_name, is_overseas=code in OVERSEAS_BASINS) basin_to_commune[code] = list() if created: nb_created += 1 else: nb_updated += 1 # Import data from csv file csv_path = os.path.abspath(options['csv_file'][0]) with open(csv_path) as csv_file: reader = csv.DictReader(csv_file, delimiter=',') for row in reader: commune_code = row['CdCommune'] basin_code = row['NumCircAdminBassin'] basin_to_commune[basin_code].append(commune_code) basins = Perimeter.objects \ .filter(scale=Perimeter.TYPES.basin) for basin in basins: basin_code = basin.code commune_codes = basin_to_commune[basin_code] attach_perimeters(basin, commune_codes) self.stdout.write( self.style.SUCCESS('%d basins created, %d updated.' % (nb_created, nb_updated)))
def form_valid(self, form): # Fetch the list of commune perimeters from the uploaded file city_codes = [] for line in form.cleaned_data['city_list']: try: code = line.decode().strip().split(';')[0] clean_code = str(code) city_codes.append(clean_code) except (UnicodeDecodeError, ValueError) as e: msg = _('This file seems invalid. \ Please double-check its content or contact the \ dev team if you feel like it\'s an error. \ Here is the original error: {}').format(e) self.messages.error(msg) return self.get(self.request, *self.args, **self.kwargs) current_perimeter = self.get_object() attach_perimeters(current_perimeter, city_codes) msg = _('We successfully updated the perimeters.') self.messages.success(msg) return super().form_valid(form)
def handle(self, *args, **options): data = {} nb_created = 0 nb_updated = 0 csv_path = os.path.abspath(options['csv_file'][0]) with open(csv_path) as csv_file: reader = csv.reader(csv_file, delimiter=',') next(reader, None) # Skip header for row in reader: perimeter_code = row[0] perimeter_name = row[1] insee_code = row[2] if perimeter_code not in data: data[perimeter_code] = { 'name': perimeter_name, 'communes': [] } insee_code = self.get_clean_insee_code(insee_code) try: perimeter_to_attach = Perimeter.objects.get( code=insee_code) except Perimeter.DoesNotExist: self.stdout.write( self.style.WARNING( f"Pour le périmetre '{perimeter_name} - {perimeter_code}', " f"le code insee n'existe pas dans la base de données : " f"'{insee_code}'")) continue # The perimeter to be attached that we found in the CSV file # could be a commune, but also an other type of perimeter, # for instance a EPCI, in that case, we need to lookup for # the commes that this perimeter contains. if perimeter_to_attach.scale != Perimeter.SCALES.commune: communes = perimeter_to_attach.contains \ .filter(scale=Perimeter.SCALES.commune) \ .values_list('code', flat=True) else: communes = [perimeter_to_attach.code] data[perimeter_code]['communes'].extend(communes) for perimeter_code in data.keys(): perimeter_name = data[perimeter_code]['name'] # Create the perimeter or update if it's code exists perimeter, created = Perimeter.objects.update_or_create( scale=Perimeter.SCALES.adhoc, code=perimeter_code, defaults={ 'name': perimeter_name, }) if created: nb_created += 1 else: nb_updated += 1 codes = data[perimeter_code]['communes'] # Link the perimeter with the related communes attach_perimeters(perimeter, codes) self.stdout.write( self.style.SUCCESS('%d adhoc perimeters created, %d updated.' % (nb_created, nb_updated)))