Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
dj-kaos-io / views.py
Size: Mime:
from typing import TYPE_CHECKING

import tablib
from django.db import models
from django.shortcuts import render
from django.urls import reverse
from django.views import View

from .exceptions import DataImportException
from .forms import ImportSpreadsheetForm

if TYPE_CHECKING:
    from . import DataImporter


class ImportView(View):
    list_view_link = None
    list_view_name = None
    verbose_name_plural = None
    verbose_name = None
    model: models.Model = None

    importer_classes = []
    template_sheets = {}

    form_class = ImportSpreadsheetForm
    template_name = 'kaos_io/import.html'

    @classmethod
    def get_opts(cls):
        return cls.model._meta

    @classmethod
    def get_list_view_link(cls):
        if cls.list_view_link:
            return cls.list_view_link
        if cls.list_view_name:
            return reverse(cls.list_view_name)
        opts = cls.get_opts()
        return reverse(f'admin:{opts.db_table}_changelist')

    @classmethod
    def get_verbose_name_plural(cls):
        if cls.verbose_name_plural:
            return cls.verbose_name_plural
        if cls.verbose_name:
            return f"{cls.verbose_name}s"
        opts = cls.get_opts()
        return opts.verbose_name_plural

    def get_default_context(self):
        return dict(
            list_view_link=self.get_list_view_link(),
            verbose_name_plural=self.get_verbose_name_plural(),
            template_sheets=self.template_sheets,
        )

    def get_importer_class(self, form):
        if len(self.importer_classes) == 1:
            return self.importer_classes[0]

        selected_importer = form.data['sheet_type']
        for importer_class in self.importer_classes:
            if importer_class.name == selected_importer:
                return importer_class
        raise

    def get(self, request, *args, **kwargs):
        context = self.get_default_context()
        form = self.form_class(importer_classes=self.importer_classes)
        context['form'] = form
        return render(request, self.template_name, context)

    def post(self, request, *args, **kwargs):
        context = self.get_default_context()
        form = self.form_class(request.POST, request.FILES, importer_classes=self.importer_classes)
        context['form'] = form
        data = tablib.import_set(form.files['spreadsheet'].read().decode('utf-8-sig'), format='csv')

        importer_class = self.get_importer_class(form)
        importer: 'DataImporter' = importer_class(data.dict)
        importer.set_context(request, *args, **kwargs)

        if importer.is_valid():
            try:
                importer.save()
            except DataImportException:
                context['errors'] = importer.errors
        else:
            context['errors'] = importer.errors

        return render(request, self.template_name, context)

    def dispatch(self, request, *args, **kwargs):
        return super(ImportView, self).dispatch(request, *args, **kwargs)