import csv import io import os from pt_map.models import * import pt_map import pt_map.class_names from django.db import models import inspect import datetime import sys def csv_queryset(q: models.query.QuerySet) -> str: fields = [field.name for field in q.model._meta.fields] result = io.StringIO() csv_writer = csv.DictWriter(result, fields) csv_writer.writeheader() for model in q: row = {} for field_name in fields: field = model._meta.get_field(field_name) value = model.__getattribute__(field.name) if value is None: continue if isinstance(field, models.DateField): row[field.name] = value.strftime("%Y%m%d") elif isinstance(field, models.ForeignKey): row[field.name] = value.pk if not model == Shape else value.shape_id elif isinstance(field, models.ManyToManyField): row[field.name] = value.all().first().__getattribute__(field.name) elif isinstance(field, models.BooleanField): row[field.name] = int(value) else: row[field.name] = value csv_writer.writerow(row) return result.getvalue() def models_csv(path: str) -> list[models.Model]: assume_compliance = True if assume_compliance: os.chdir(path) feed = None order = [] for m in [*pt_map.class_names.fks.values(), *pt_map.class_names.mtm.values(), *[m for _,m in inspect.getmembers(pt_map.models, inspect.isclass)]]: if m not in order: order.append(m) for m in order: if os.path.exists(pt_map.class_names.file_names[m]): with open(pt_map.class_names.file_names[m], 'r') as f: csvreader = csv.DictReader(f) mtm = {} for row in csvreader: for field in [field for field in m._meta.fields if field.name in csvreader.fieldnames]: if not row[field.name]: del row[field.name] continue if isinstance(field, models.ForeignKey): row[field.name] = pt_map.class_names.fks[field.name].objects.get(pk=f"{feed.pk}_{row[field.name]}") elif isinstance(field, models.DateField): row[field.name] = datetime.datetime.fromisoformat(row[field.name]) elif (field.primary_key and feed) or field.name == 'service_id': row[field.name] = f"{feed.pk}_{row[field.name]}" for field in m._meta.many_to_many: mtm[field.name] = pt_map.class_names.mtm[field.name].objects.filter(**{field.name: row[field.name]}) del row[field.name] if feed: row['feed_info_id'] = feed if m == pt_map.models.Shape: row['shape_id'] = f"{feed.pk}_{row['shape_id']}" obj = m.objects.create(**row) for name, value in mtm.items(): getattr(obj, name).set(value) if not feed: feed = obj