def test_parsedate_timezone(self):
     tab_format_date = [
         '2015-01-01', '20150101', '01-01-2015', '01/01/2015', '2015/01/01'
     ]
     for format_date in tab_format_date:
         self.assertEqual(
             parsedate(format_date).tzinfo.zone, settings.TIME_ZONE)
 def test_parsedate_format_date(self):
     tab_format_date = [
         '2015-01-01', '20150101', '01-01-2015', '01/01/2015', '2015/01/01'
     ]
     for format_date in tab_format_date:
         self.assertIsInstance(parsedate(format_date, date_only=True),
                               datetime.date)
 def test_parsedate_utc(self):
     tab_format_date = [
         '2015-01-01', '20150101', '01-01-2015', '01/01/2015', '2015/01/01'
     ]
     for format_date in tab_format_date:
         self.assertEqual(
             parsedate(format_date, utc=True).tzinfo.zone, 'UTC')
 def test_parsedatetime_datetime(self):
     tab_format_datetime = [
         '2015-01-01 18:25:52', '20150101 18:25:52', '01-01-2015 18:25:52',
         '01/01/2015 18:25:52', '2015/01/01 18:25:52'
     ]
     for format_datetime in tab_format_datetime:
         self.assertIsInstance(parsedate(format_datetime),
                               datetime.datetime)
Exemple #5
0
def filter_parsedate(value, options=''):
    """
    Parse une date ou un datetime dans n'importe quel format
    :param value: Date ou datetime au format texte
    :param options: Options de parsing (au format query string)
    :return: Date ou datetime
    """
    from common.utils import parsedate
    options = QueryDict(options)
    return parsedate(value, **options)
Exemple #6
0
 def wrapper(item, *args, **kwargs):
     # "request = item.request" dans le cas d'une ViewSet, "item" dans le cas d'une api_view
     request = item.request if hasattr(item, 'request') else item
     valid = None
     valid_date = None
     params = request.data if request.data else request.query_params
     if params:
         valid = str_to_bool(params.get('valid', None))
         valid_date = parsedate(params.get('valid_date', None))
     setattr(request, 'valid', valid)
     setattr(request, 'valid_date', valid_date)
     setattr(request, 'valid_filter', dict(valid=valid, date=valid_date))
     return func(item, *args, **kwargs)
 def test_parsedate_initial(self):
     tab_format_date = [
         '2015-01-01', '20150101', '01-01-2015', '01/01/2015', '2015/01/01'
     ]
     for format_date in tab_format_date:
         self.assertEqual(parsedate(format_date).year, 2015)
         self.assertEqual(parsedate(format_date).month, 1)
         self.assertEqual(parsedate(format_date).day, 1)
         self.assertEqual(parsedate(format_date).hour, 0)
         self.assertEqual(parsedate(format_date).minute, 0)
         self.assertEqual(parsedate(format_date).second, 0)
         self.assertEqual(parsedate(format_date).microsecond, 0)
 def test_parsedate_end_day(self):
     tab_format_date = [
         '2015-01-01', '20150101', '01-01-2015', '01/01/2015', '2015/01/01'
     ]
     for format_date in tab_format_date:
         self.assertEqual(parsedate(format_date).year, 2015)
         self.assertEqual(parsedate(format_date).month, 1)
         self.assertEqual(parsedate(format_date).day, 1)
         self.assertEqual(parsedate(format_date, end_day=True).hour, 23)
         self.assertEqual(parsedate(format_date, end_day=True).minute, 59)
         self.assertEqual(parsedate(format_date, end_day=True).second, 59)
         self.assertEqual(
             parsedate(format_date, end_day=True).microsecond, 999999)
 def test_parsedatetime(self):
     tab_format_date = ['2015-01-01 150205', '20150101 15:02:05']
     for format_date in tab_format_date:
         self.assertEqual(parsedate(format_date).year, 2015)
         self.assertEqual(parsedate(format_date).month, 1)
         self.assertEqual(parsedate(format_date).day, 1)
         self.assertEqual(
             parsedate(format_date, start_day=True, end_day=True).hour, 15)
         self.assertEqual(
             parsedate(format_date, start_day=True, end_day=True).minute, 2)
         self.assertEqual(
             parsedate(format_date, start_day=True, end_day=True).second, 5)
         self.assertEqual(
             parsedate(format_date, start_day=True,
                       end_day=True).microsecond, 0)
Exemple #10
0
    def importer(self, file):
        """
        Importe les données d'un document Excel de tarification
        :param file: Chemin vers le document Excel
        :return: Cache
        """
        cache = {}
        metadata = {}

        workbook = load_workbook(filename=file, read_only=True, data_only=True)
        # Récupération de toutes les feuilles par nom
        worksheets = {}
        for worksheet in workbook.worksheets:
            worksheets[worksheet.title.lower()] = worksheet

        # Si elle existe, nous traitons la feuille des métadonnées
        metadata_sheet_name = str(METADATA_NAME)
        if metadata_sheet_name in worksheets:
            worksheet = worksheets.get(metadata_sheet_name)
            headers = {}
            title = True
            for row_number, row in enumerate(worksheet.iter_rows()):
                code_meta = ''
                line = []
                for col_number, cell in enumerate(row):
                    value = cell.value
                    if isinstance(value, str):
                        value = value.strip()
                    if value is None or not str(value).strip():
                        continue
                    # Si c'est la ligne des titres, on ne récupère que les données liées aux colonnes
                    if title:
                        value = value.lower()
                        headers[col_number] = value
                        continue
                    field = headers[col_number]
                    if field == 'code':
                        if value not in metadata:
                            metadata[value] = []
                        code_meta = value
                        continue
                    line.append(value)
                # Si c'est la ligne des titres, on n'enregistre aucune donnée
                if title:
                    title = False
                    continue
                metadata[code_meta].append(line)

        done = []
        for model in self.models:
            code_field = getattr(model, '_code_field', 'id')
            # Retrait des espaces et des caractères superflus
            model_name = re.sub(r'[^\w]+', ' ',
                                str(model._meta.verbose_name).lower())
            # Récupération de la feuille correspondante au modèle
            if model_name not in worksheets:
                self.log.warning(
                    _("La feuille correspondant au modèle '{model_name}' "
                      "n'a pu être trouvée dans le fichier.").format(
                          model_name=model_name))
                continue
            worksheet = worksheets.get(model_name)
            # Récupération des champs du modèle
            fields = {}
            for field in chain(model._meta.fields, model._meta.many_to_many):
                if field.name != code_field and (
                        field.auto_created
                        or not (field.editable or self.non_editables)):
                    continue
                field.m2m = field in model._meta.many_to_many
                fields[str(field.verbose_name).lower()] = field
            # Parcours des lignes de la feuille
            self.delayed_models = []
            headers = {}
            title = True
            for row_number, row in enumerate(worksheet.iter_rows()):
                instance = model()
                current_metadata = {}
                delayed = False
                m2m = {}
                fks = {}
                # Parcours des cellules de la ligne
                has_data = False
                for col_number, cell in enumerate(row):
                    # Récupération de la valeur de la cellule, ignorée si vide
                    value = cell.value
                    if isinstance(value, str):
                        value = value.strip()
                    if value is None or not str(value).strip():
                        continue
                    # Si c'est la ligne des titres, on ne récupère que les données liées aux colonnes
                    if title:
                        value = value.lower()
                        if value in fields:
                            headers[col_number] = fields[value]
                        continue
                    # Si la colonne n'est pas référencée comme un champ connu, elle est ignorée
                    if col_number not in headers:
                        continue
                    field = headers[col_number]
                    # Gestion des types spécifiques mal gérés par Excel
                    type = field.get_internal_type()
                    if field.m2m:
                        if field.related_model == model:
                            delayed = True
                        value = [v.strip() for v in value.split(',')]
                        m2m[field.name] = (field.related_model, value)
                        has_data = True
                        continue
                    elif field.remote_field is not None and field.related_model is MetaData:
                        current_metadata = dict(metadata.get(value, []))
                        continue
                    elif field.remote_field:
                        if field.related_model == model:
                            delayed = True
                        fks[field.name] = (field.related_model, value)
                        has_data = True
                        continue
                    elif field.choices:
                        choices = {
                            str(value): str(key)
                            for key, value in field.flatchoices
                        }
                        if hasattr(field, 'max_choices'):  # MultiSelectField
                            value = [
                                choices[val] for val in choices.keys()
                                if val in value
                            ]
                        else:
                            value = choices[value]
                    elif type in ['DateField', 'DateTimeField']:
                        value = parsedate(value, dayfirst=True)
                    elif type == 'DecimalField':
                        value = decimal(value, precision=20)
                    elif type == 'BooleanField':
                        value = str_to_bool(value)
                    has_data = True
                    # Récupération des données existantes
                    if field.name == code_field and field.unique:
                        existing = model.objects.filter(**{code_field: value})
                        if existing.count() == 1:
                            instance = existing.first()
                    # Modification des propriétés du modèle
                    setattr(instance, field.name, value)
                # Si c'est la ligne des titres, on n'enregistre aucune donnée
                if title:
                    title = False
                    continue
                # Si la ligne est vide, on passe à la suivante
                if not has_data:
                    continue
                # Mise en cache de l'instance  courante
                code = getattr(instance, code_field, id(instance))
                if model not in cache:
                    cache[model] = {}
                cache[model][code] = instance
                # Enregistrement immédiat (si possible)
                if delayed:
                    self.delayed_models.append(
                        (instance, fks, m2m, current_metadata))
                    continue
                self._save_instance(instance,
                                    metadata=current_metadata,
                                    cache=cache,
                                    fks=fks,
                                    m2m=m2m)
            # Enregistrement différé
            for instance, fks, m2m, current_metadata in self.delayed_models:
                self._save_instance(instance,
                                    metadata=current_metadata,
                                    cache=cache,
                                    fks=fks,
                                    m2m=m2m)
            # Intégration terminée
            done.append(model)
        return cache
 def test_obj_datetime_ok(self):
     from datetime import datetime
     self.assertIsInstance(parsedate(datetime(2000, 1, 1)), datetime)
     self.assertEqual(parsedate(datetime(2000, 1, 1)).year, 2000)
     self.assertEqual(parsedate(datetime(2000, 1, 1)).month, 1)
     self.assertEqual(parsedate(datetime(2000, 1, 1)).day, 1)
 def test_parsedate_isoformat_yyyymmdd(self):
     format_date = '20030925'
     self.assertIsInstance(parsedate(format_date), datetime.datetime)
 def test_parsedate_isoformat_yyyymmddthhmmsstz(self):
     format_date = '20030925T104941-0300'
     self.assertIsInstance(parsedate(format_date), datetime.datetime)
 def test_parsedate_bisextil_ko(self):
     format_date = '2015-02-29'
     self.assertIsNone(parsedate(format_date))
 def test_parsedate_ecrit_yyyy(self):
     format_date = '2003'
     self.assertIsInstance(parsedate(format_date), datetime.datetime)
 def test_parsedate_ecrit_mmm(self):
     format_date = 'Dec'
     self.assertIsInstance(parsedate(format_date), datetime.datetime)
Exemple #17
0
 def _write_model(self, workbook, model):
     """
     Ecrit le modèle dans un document Excel ouvert
     :param workbook: Document Excel
     :param model: Modèle
     :return: Rien
     """
     meta = model._meta
     code_field = getattr(model, '_code_field', 'id')
     worksheet = workbook.create_sheet(
         title=re.sub(r'[^\w]+', ' ',
                      str(meta.verbose_name).capitalize()))
     widths = {}
     dropdowns = {}
     # Titres
     fields = [
         (
             field.name,
             str(field.verbose_name),
         ) for field in chain(meta.fields, meta.many_to_many)
         if field.name == code_field or not (field.auto_created or not (
             field.editable or self.non_editables))
     ]
     for column, (field_code, field_name) in enumerate(fields, start=1):
         cell = worksheet.cell(row=1, column=column)
         cell.value = field_name
         cell.font = self.title_font
         column_letter = get_column_letter(column)
         widths[column_letter] = len(str(cell.value)) + CELL_OFFSET
     # Récupération des données
     queryset = model.objects.select_related().order_by(code_field)
     row = 2
     for element in queryset:
         for column, (field_code, field_name) in enumerate(fields, start=1):
             value = getattr(element, field_code)
             if value is None:
                 continue
             field = meta.get_field(field_code)
             if field.many_to_many:
                 m2m_code_field = getattr(field.related_model,
                                          '_code_field', 'id')
                 value = ', '.join(
                     str(v)
                     for v in value.values_list(m2m_code_field, flat=True))
             elif field.related_model is not None and field.related_model is MetaData:
                 if len(element.get_metadata()) > 0:
                     value = 'meta_{}_{}'.format(element._meta.model_name,
                                                 row)
                     self.metadata[value] = []
                     for key_meta, value_meta in element.get_metadata(
                     ).items():
                         self.metadata[value].append((
                             key_meta,
                             value_meta,
                         ))
                 else:
                     continue
             elif field.remote_field:
                 if not value:
                     value = ''
                 else:
                     value = getattr(value, code_field, value.id)
             elif field.choices:
                 value = getattr(element,
                                 'get_{}_display'.format(field_code))()
                 if column not in dropdowns:
                     data_validation = dropdowns[column] = self.dropdowns[
                         model, field_code]
                     worksheet.add_data_validation(data_validation)
                 dropdowns[column].add(worksheet["{}{}".format(
                     get_column_letter(column), row)])
             elif field.get_internal_type() in [
                     'DateField', 'DateTimeField'
             ]:
                 value = parsedate(value).isoformat()
             elif isinstance(value, FieldFile):
                 value = value.name
             elif isinstance(value, dict):
                 value = json_encode(value)
             cell = worksheet.cell(row=row, column=column)
             try:
                 cell.value = value
             except Exception:
                 cell.value = str(value)
             column_letter = get_column_letter(column)
             widths[column_letter] = max(widths[column_letter],
                                         len(str(value)) + CELL_OFFSET)
         row += 1
     # Ajout de lignes vides avec listes déroulantes
     for row in range(row, row + 10):
         for column, (field_code, field_name) in enumerate(fields, start=1):
             field = meta.get_field(field_code)
             if not field.choices:
                 continue
             if column not in dropdowns:
                 data_validation = dropdowns[column] = self.dropdowns[
                     model, field_code]
                 worksheet.add_data_validation(data_validation)
             dropdowns[column].add(worksheet["{}{}".format(
                 get_column_letter(column), row)])
     # Redimensionne les colonnes
     for column_letter, width in widths.items():
         worksheet.column_dimensions[column_letter].width = width
 def test_parsedate_ecrit_dddddmmyyyy(self):
     format_date = 'Thu, 25 Dec 2003'
     self.assertIsInstance(parsedate(format_date), datetime.datetime)
 def test_parsedate_format_ko(self):
     format_date = '01012016'
     self.assertIsNone(parsedate(format_date))
 def test_parsedate_bisextil_ok(self):
     format_date = '2016-02-29'
     self.assertIsInstance(parsedate(format_date), datetime.datetime)
 def test_parsedate_none(self):
     self.assertIsNone(parsedate('chaine'))
 def test_parsedate_ecrit_dddddmmyyyyhhmmss(self):
     format_date = 'Thu, 25 Dec 2003 10:49:41 -0300'
     self.assertIsInstance(parsedate(format_date), datetime.datetime)
 def test_parsedate_ecrit_yyyymmddthhmmssxtz(self):
     format_date = '2003-09-25T10:49:41.5-03:00'
     self.assertIsInstance(parsedate(format_date), datetime.datetime)