# -*- coding: utf-8 -*- from django import forms from django.conf import settings from theme.models import Theme, Tag from place_exposition.models import PlaceExposition from place_conference.models import PlaceConference from country.models import Country from organiser.models import Organiser from django.db.models.loading import get_model import xlrd, xlwt from excel_settings import import_settings languages = [code for code in settings.LANGUAGES] class ImportForm(forms.Form): """ abstract form for importing models from excel file to database """ model = None excel_file = forms.FileField(label='Выберите файл') language = forms.ChoiceField(label='Выберите язык', choices=languages) def save_file(self): data = self.cleaned_data lang = data['language'] f = data['excel_file'] book = xlrd.open_workbook(file_contents=f.read()) sheet = book.sheet_by_index(0) row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] # all field names in excel file (must be in second row) field_names = [name for name in row_list[1]] for row_number, row in enumerate(row_list): # go through all rows in file if row_number > 1: # first two fields are verbose name and name if row[0] != '': # in first column ids try: object = self.model.objects.language(lang).get(id=int(row[0])) except ValueError: object = self.model() object.translate(lang) except self.model.DoesNotExist: object = self.model(id= int(row[0])) object.translate(lang) else: # if id blank - its a new event object = self.model() object.translate(lang) for col_number, cell in enumerate(row): # go through row cells # field name current cell field_name = field_names[col_number] if field_name =='theme': # need save object before saving manytomany field object.save() setting = import_settings.get(field_name) if setting is not None: # if setting exist for this field func = setting.get('func') if func is not None: extra_value = setting.get('extra_values') if extra_value is not None: # if setting has extra value then # it is some field like city, theme, tag # that has relation and can be created # in function we add language(need for relation fields) # and extra value from object (like for city need country) value = func(cell, lang, getattr(object, extra_value)) else: value = func(cell) setattr(object, field_name, value) object.save() class ImportOrganiserForm(ImportForm): model = Organiser class ImportThemeForm(ImportForm): model = Theme class ImportPlaceExpositionForm(ImportForm): model = PlaceExposition class ImportPlaceConferenceForm(ImportForm): model = PlaceConference class ImportEventForm(ImportForm): """ extended form for importing one type of event """ event = forms.ChoiceField(label='Выберите тип события', choices=[('exposition.Exposition', 'Выставка'), ('conference.Conference', 'Конференция'), ('seminar.Seminar', 'Семинар'), ('webinar.Webinar', 'Вебинар')]) def save_file(self): """ save events from excel file in language from form """ data = self.cleaned_data lang = data['language'] f = data['excel_file'] book = xlrd.open_workbook(file_contents=f.read()) sheet = book.sheet_by_index(0) row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] # all field names in excel file (must be in second row) field_names = [name for name in row_list[1]] # model model = get_model(data['event'].split('.')[0], data['event'].split('.')[1]) for row_number, row in enumerate(row_list): # go through all rows in file if row_number > 1: # first two fields are verbose name and name if row[0] != '': # in first column ids try: object = self.model.objects.language(lang).get(id=int(row[0])) except ValueError: object = self.model() object.translate(lang) except self.model.DoesNotExist: object = self.model(id= int(row[0])) object.translate(lang) else: # if id blank - its a new event object = model() object.translate(lang) for col_number, cell in enumerate(row): # go through row cells # field name current cell field_name = field_names[col_number] if field_name =='theme': # need save object before saving manytomany field object.save() setting = import_settings.get(field_name) if setting is not None: # if setting exist for this field func = setting.get('func') if func is not None: extra_value = setting.get('extra_values') if extra_value is not None: # if setting has extra value then # it is some field like city, theme, tag # that has relation and can be created # in function we add language(need for relation fields) # and extra value from object (like for city need country) if cell: value = func(cell, lang, getattr(object, extra_value)) else: value = None else: value = func(cell) if value: setattr(object, field_name, value) object.save() class ImportTagForm(ImportForm): """ hacked problem with importing theme field in save_file method """ model = Tag def save_file(self): data = self.cleaned_data lang = data['language'] f = data['excel_file'] book = xlrd.open_workbook(file_contents=f.read()) sheet = book.sheet_by_index(0) row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] # all field names in excel file (must be in second row) field_names = [name for name in row_list[1]] for row_number, row in enumerate(row_list): # go through all rows in file if row_number > 1: # first two fields are verbose name and name if row[0] != '': # in first column ids try: object = self.model.objects.language(lang).get(id=int(row[0])) except ValueError: object = self.model() object.translate(lang) except self.model.DoesNotExist: object = self.model(id= int(row[0])) object.translate(lang) else: # if id blank - its a new event object = self.model() object.translate(lang) for col_number, cell in enumerate(row): # go through row cells # field name current cell field_name = field_names[col_number] setting = import_settings.get(field_name) if setting is not None: # if setting exist for this field func = setting.get('func') if func is not None: extra_value = setting.get('extra_values') if extra_value is not None: # if setting has extra value then # it is some field like city, theme, tag # that has relation and can be created # in function we add language(need for relation fields) # and extra value from object (like for city need country) value = func(cell, lang, getattr(object, extra_value)) else: value = func(cell) if field_name != 'theme': setattr(object, field_name, value) else: setattr(object, field_name, value[0]) object.save()