def _create_data_validation(self, field): allow_blank = not util_model.is_mandatory(field) dv = None if util_model.is_lookup_field(field) and util_model.has_related_objects(field): # here we expect that the lookup has been registered as named range. # The name of the lookup is the lookup model name (see _write_lookups) strict = util_model.is_strict_lookup_field(field) lookup_name = util_model.get_field_lookup_model_name(field) dv = util_xls.create_list_validation(lookup_name, strict=strict, allow_blank=allow_blank) elif util_model.has_choices(field): # Should we also add the choices in the Lookups sheet? values = [str(choice[1]) for choice in util_model.get_field_choices(field)] strict = True dv = util_xls.create_list_validation(values, strict=strict, allow_blank=allow_blank) elif util_model.is_boolean_field(field): allow_blank = True # blank is False values = ['Y', 'N'] strict = False dv = util_xls.create_list_validation(values, strict=strict, allow_blank=allow_blank) # species. Hack! Last minute update. We want species data validation on animals only elif util_model.is_species_observation_field(field)\ and self.file_species is not None \ and field.model._meta.app_label == 'animals': # we expect here that a range call species has been registered (see _write_species) strict = False dv = util_xls.create_list_validation('species', strict=strict, allow_blank=allow_blank) return dv
def test_is_species_field(self): # filter species field from the StratumSpecies model. There should only be one species_name_fields = [f for f in StratumSpecies._meta.fields if is_species_observation_field(f)] self.assertEqual(1, len(species_name_fields), msg="There should be only one species field in StratumSpecies model") field = species_name_fields[0] self.assertTrue(field.related_model == SpeciesObservation)
def get_field_data(field_): return { 'name': field_.name, 'is_datasheet_field': utils_model.is_template_field(field_), 'datasheet_name': utils_model.get_datasheet_field_name(field_), 'is_lookup': utils_model.is_lookup_field(field_), 'is_mandatory': utils_model.is_mandatory(field_), 'is_species_name': utils_model.is_species_observation_field(field_), 'is_strict_lookup': utils_model.is_strict_lookup_field(field_), 'is_boolean': utils_model.is_boolean_field(field_), 'is_extra_species_attribute': utils_model.is_species_observation_extra_attribute(field), }
def to_field_value_raise(field, value, commit=True, site_visit=None, row_data=None): if is_blank(value): if util_model.is_mandatory(field): message = "Mandatory field with no data {field}.".format(field=field.verbose_name) raise ValidationException(message) # Every next conversion functions should handle a blank/None value if util_model.is_lookup_field(field): return to_lookup_raise(field, value, commit=commit) if util_model.has_choices(field): return to_choice_raise(field, value) if util_model.is_boolean_field(field): return to_boolean_raise(value) if util_model.is_integer_field(field): return to_integer_raise(value) if util_model.is_float_field(field): return to_float_raise(value) if util_model.is_date_field(field): return to_date_raise(value) if util_model.is_string_field(field): return to_string(value) if util_model.is_species_observation_field(field): return to_species_observation_raise(value, site_visit, commit=commit, row_data=row_data) return value
def _write_model(self, mapping): model = mapping.model ws = util_xls.get_or_create_sheet(self.wb, mapping.sheet_name) fields = util_model.get_datasheet_fields_for_model(model) top_cell = ws.cell(row=mapping.top_left_row, column=mapping.top_left_column) column_cell = top_cell # create alignment for transposed header cells right_alignment = Alignment(horizontal='right') max_column_width = 0 for field in fields: # the column header col_header = util_model.get_datasheet_field_name(field) column_cell.font = self.column_header_font column_cell.value = col_header if mapping.transpose: column_cell.alignment = right_alignment # calculate column widths if util_model.is_species_observation_field(field): # special case for species column width ws.column_dimensions[column_cell.column].width = SPECIES_COLUMN_WIDTH else: column_width = len(column_cell.value) + COLUMN_WIDTH_BUFFER if mapping.transpose: if column_width > max_column_width: max_column_width = column_width else: column_width = max_column_width ws.column_dimensions[column_cell.column].width = column_width dv = self._create_data_validation(field) if dv is not None: # apply data validation to the row cell row_cell = util_xls.get_cell_neighbour(column_cell, mapping.next_row_direction) dv.add(row_cell) if not mapping.unique: # it is a multi row model. We need to extend the data validation to other rows # choose a max row max_row = self.max_row for i in range(0, max_row): row_cell = util_xls.get_cell_neighbour(row_cell, mapping.next_row_direction) dv.add(row_cell) ws.add_data_validation(dv) column_cell = util_xls.get_cell_neighbour(column_cell, mapping.next_col_direction) # insert formulas for field_name in mapping.formulas: field = mapping.model._meta.get_field_by_name(field_name)[0] field_header_cell = util_xls.find_cell_by_value(ws, util_model.get_datasheet_field_name(field)) field_cell = util_xls.get_cell_neighbour(field_header_cell, mapping.next_row_direction) parameter_cells = [] for param_field_name in mapping.formulas[field_name]['parameters']: param_field = mapping.model._meta.get_field_by_name(param_field_name)[0] param_header_cell = util_xls.find_cell_by_value(ws, util_model.get_datasheet_field_name(param_field)) parameter_cells.append(util_xls.get_cell_neighbour(param_header_cell, mapping.next_row_direction)) field_cell.value = self._create_formula(mapping.formulas[field_name]['formula'], *parameter_cells) if not mapping.unique: # it is a multi row model. We need to extend the formula to other rows choose a max row max_row = self.max_row for i in range(0, max_row): field_cell = util_xls.get_cell_neighbour(field_cell, mapping.next_row_direction) parameter_cells = [util_xls.get_cell_neighbour(cell, mapping.next_row_direction) for cell in parameter_cells] field_cell.value = self._create_formula(mapping.formulas[field_name]['formula'], *parameter_cells)