# -*- 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 from excel_settings import place_exp_sett from django.db import IntegrityError import urllib, json def google_address(address): if address: address = address.encode('utf') params = urllib.urlencode({'sensor': 'false', 'address': address}) response = urllib.urlopen("http://maps.google.com/maps/api/geocode/json?%s" % params) response = response.read() results = json.loads(response).get('results') if results: response = {'address' : results[0].get('formatted_address'), 'lat' : results[0]['geometry']['location']['lat'], 'lng' : results[0]['geometry']['location']['lng']} return json.dumps(response) else: return '' return '' from djutils.decorators import async from djutils.queue.decorators import queue_command class ImportPlaceExpositionForm(ImportForm): model = PlaceExposition settings = place_exp_sett #@async 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)] labels = [label for label in row_list[0]] for row_number, row in enumerate(row_list): # go through all rows in file if row_number > 0: # first field is label 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) methods = [] for col_number, cell in enumerate(row): # go through row cells # field name current cell label = labels[col_number] setting = place_exp_sett.get(label) if setting is None: continue if setting.get('method'): if cell != "": methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')}) continue field_name = setting['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 =='adress': setattr(object, 'address', google_address(value)) setattr(object, field_name, value) try: object.save() except IntegrityError: continue #url = object.url + translit_with_separator(object.city.name) #object.url = url #object.save() for method in methods: func = method['func'] if method.get('purpose'): try: func(object, method['value'], method['purpose']) except: continue else: try: func(object, method['value']) except: continue class ImportPlaceConferenceForm(ImportForm): model = PlaceConference from import_xls.excel_settings import event_sett 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[0]] # model model = get_model(data['event'].split('.')[0], data['event'].split('.')[1]) list_dicts = [] for row_number, row in enumerate(row_list[1:]): d = {} for col_number, cell in enumerate(row): # through row field_name = field_names[col_number] setting = event_sett.get(field_name) if setting: d[setting['field']] = {'value':cell} d['lang'] = lang list_dicts.append(d) return list_dicts for row_number, row in enumerate(row_list): # go through all rows in file if row_number > 0: # 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) d = {} for col_number, cell in enumerate(row): # through row field_name = field_names[col_number] setting = import_settings.get(field_name) d[setting] = cell list_dicts.append(d) """ # 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) d[setting] = cell 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() sadsa class ImportTagForm(ImportForm): """ hacked problem with importing theme field in save_file method """ model = Tag #@async 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()