Import events view

remotes/origin/1203
Nazar Kotjuk 12 years ago
parent 72847d4d71
commit cdcf6abcb5
  1. 36
      functions/translate.py
  2. 1
      import_xls/__init__.py
  3. 136
      import_xls/custom_forms.py
  4. 98
      import_xls/excel_settings.py
  5. 175
      import_xls/views.py
  6. 2
      proj/admin_urls.py
  7. 1
      proj/settings.py
  8. 92
      templates/admin/import templates/export_event.html
  9. 42
      templates/admin/import templates/import_event.html
  10. 6
      templates/base.html
  11. 2
      webinar/models.py

@ -88,4 +88,38 @@ def populate_all(Model, data={}, id=None, zero_fields={}):
else:
obj = Model._meta.translations_model.objects.get(language_code = code,master__id=id)
populate(obj,data,code,zero_fields)
obj.save()
obj.save()
def get_all_fields(obj, exclude_fields=[]):
"""
Return all simple fields with translated hvad fields
can exclude some fields
"""
# simple fields from django object
fields = [i for i in obj._meta.get_all_field_names() if i not in exclude_fields]
# get hvad translation objects
translation = obj.translations.all()
# fields which present in database but don't need
bad_fields = ['id', 'master', 'language_code']
# get translated fields without bad fields and exclude fields
translated_fields = [i.name for i in translation[0]._meta.fields if i.name not in bad_fields and i.name not in exclude_fields]
# fields += translated_fields
# rields2 = [fields for i in field_settings]
return fields
def get_all_verbose_names(obj, fields):
names = {}
for field in fields:
try:
names[field] = obj._meta.get_field_by_name(field)[0].verbose_name
except:
translations = obj.translations.all()
tr = translations[0]
names[field] = tr._meta.get_field_by_name(field)[0].verbose_name
return names

@ -0,0 +1,136 @@
# -*- coding: utf-8 -*-
from django import forms
from django.conf import settings
languages = [code for code in settings.LANGUAGES]
class ImportEventForm(forms.Form):
excel_file = forms.FileField(label='Выберите файл')
event = forms.ChoiceField(label='Выберите тип события', choices=[('exposition', 'Выставка'),
('conference', 'Конференция'),
('seminar', 'Семинар'),
('webinar', 'Вебинар')])
language = forms.ChoiceField(label='Выберите язык', choices=languages)
from theme.models import Theme
from country.models import Country
from django.db.models.loading import get_model
import StringIO
from functions.translate import get_all_fields, get_all_verbose_names
class ExportEventForm(forms.Form):
event = forms.ChoiceField(label='Выберите тип события', choices=[('exposition.Exposition', 'Выставка'),
('conference.Conference', 'Конференция'),
('seminar.Seminar', 'Семинар'),
('webinar.Webinar', 'Вебинар')])
language = forms.ChoiceField(label='Выберите язык', choices=languages)
date_from = forms.DateField(label='С')
date_to = forms.DateField(label='До')
theme = forms.ModelMultipleChoiceField(label='Направление', queryset=Theme.objects.all(), required=False)
country = forms.ModelMultipleChoiceField(label='Страны', queryset=Country.objects.all(), required=False)
def generate_dicts(self):
data = self.cleaned_data
event = data['event']
language = data['language']
date_from = data['date_from']
date_to = data['date_to']
theme = data['theme']
country = data['country']
# get model of event
model = get_model(event.split('.')[0], event.split('.')[1])
#
objects = model.objects.language(language).filter(data_begin__range=[date_from, date_to],
country__in=country,
theme__in=theme
).distinct()
if not objects:
return None
# get fields
# in list exclude fields
fields = get_all_fields(objects[0],['organiser', 'tag', 'descriptions', 'keywords', 'title', 'theme',
'users', 'company', 'translations', 'business_program', 'created',
'modified'])
# readable names
names = get_all_verbose_names(objects[0], fields)
objects_list = []
for object in objects:
obj_dict = {}
# generate dict with field values
for field in fields:
obj_dict = {'name': field, 'value': getattr(object, field),
'verbose_name': names[field]}
#obj_dict[field] = {'value': getattr(object, field), 'verbose_name': names[field]}
objects_list.append(obj_dict)
return objects_list
"""
def generate_dicts(self):
data = self.cleaned_data
event = data['event']
language = data['language']
date_from = data['date_from']
date_to = data['date_to']
theme = data['theme']
country = data['country']
# get model of event
model = get_model(event.split('.')[0], event.split('.')[1])
#
objects = model.objects.language(language).filter(data_begin__range=[date_from, date_to],
country__in=country,
theme__in=theme
).distinct()
if not objects:
return None
# get fields
# in list exclude fields
fields = get_all_fields(objects[0],['organiser', 'tag', 'descriptions', 'keywords', 'title', 'theme',
'users', 'company', 'translations', 'business_program', 'created',
'modified'])
# readable names
names = get_all_verbose_names(objects[0], fields)
objects_list = []
for object in objects:
obj_dict = {}
# generate dict with field values
for field in fields:
obj_dict[field] = {'value': getattr(object, field), 'verbose_name': names[field]}
objects_list.append(obj_dict)
return objects_list
"""
def clean_theme(self):
"""
Set all themes if no theme selected
"""
theme = self.cleaned_data.get('theme')
if not theme:
theme = Theme.objects.all()
return theme
def clean_country(self):
"""
Set all countries if no country selected
"""
country = self.cleaned_data.get('country')
if not country:
country = Country.objects.all()
return country

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
import xlwt
import datetime
def get_bool(value):
if value:
return 1
return 0
def get_int(value):
if not value:
return ''
return value
def get_audience(value):
if not value:
return 'Не выбрано'
elif value == 'experts':
return 'Специалисты'
elif value == 'experts and consumers':
return 'Специалисты и потребители'
elif value == 'general public':
return 'Широкая публика'
field_settings = [
{'name': 'id', 'verbose_name': 'id', 'type': get_int, 'width':1500},
{'name': 'url', 'verbose_name': 'url', 'type': str},
{'name': 'name', 'verbose_name': 'Имя', 'type': str, 'width':8000,},
{'name': 'data_begin', 'verbose_name': 'Дата начала', 'type': str},
{'name': 'data_end', 'verbose_name': 'Дата окончания', 'type': str},
{'name': 'main_title', 'verbose_name': 'Краткое описание', 'type': str},
{'name': 'description', 'verbose_name': 'Описание', 'type': str},
{'name': 'audience', 'verbose_name': 'Аудитория', type: get_audience},
{'name': 'country', 'verbose_name': 'Страна', 'type': str},
{'name': 'city', 'verbose_name': 'Город', 'type': str},
{'name': 'periodic', 'verbose_name': 'Периодичность', 'type': str},
{'name': 'web_page', 'verbose_name': 'Веб страница', 'type': str},
{'name': 'time', 'verbose_name': 'Время проведения', 'type': str},
{'name': 'products', 'verbose_name': 'Экспонируемые продукты', 'type': str},
{'name': 'foundation_year', 'verbose_name': 'Год основания', 'type': get_int},
{'name': 'tax', 'verbose_name': 'Налог включен', 'type': get_bool, 'width':1000},
{'name': 'currency', 'verbose_name': 'Валюта', 'type': str},
{'name': 'max_price', 'verbose_name': 'Максимальная цена', 'type': get_int},
{'name': 'min_price', 'verbose_name': 'Минимальная цена', 'type': get_int},
{'name': 'registration_payment', 'verbose_name': 'Регистрационный взнос', 'type': get_int},
{'name': 'min_closed_area', 'verbose_name': 'Минимальная цена закрытой НЕ оборудованной площади', 'type': get_int},
{'name': 'max_closed_area', 'verbose_name': 'Максимальная цена закрытой НЕ оборудованной площади', 'type': get_int},
{'name': 'min_closed_equipped_area', 'verbose_name': 'Минимальная цена закрытой оборудованной площади ', 'type': get_int},
{'name': 'max_closed_equipped_area', 'verbose_name': 'Максимальная цена закрытой оборудованной площади', 'type': get_int},
{'name': 'min_open_area', 'verbose_name': 'Минимальная цена закрытой площади', 'type': get_int},
{'name': 'max_open_area', 'verbose_name': 'Максимальная цена открытой площади', 'type': get_int},
{'name': 'min_area', 'verbose_name': 'Минимальная площадь', 'type': get_int},
{'name': 'max_area', 'verbose_name': 'Максимальная площадь', 'type': get_int},
{'name': 'is_published', 'verbose_name': 'Опубликована', 'type': get_bool, 'width':1000},
{'name': 'canceled_by_administrator', 'verbose_name': 'Отменена администратором', 'type': get_bool, 'width':1000}
]
def get_cell(field_name, value):
return {'tax': get_bool(value), 'foundation_year': get_int(value), 'max_closed_area': get_int(value),
'min_closed_equipped_area': get_int(value), 'registration_payment': get_int(value),
'max_closed_equipped_area': get_int(value), 'max_open_area': get_int(value), 'min_closed_area': get_int(value),
'min_area': get_int(value), 'canceled_by_administrator': get_bool(value), 'is_published': get_bool(value),
'min_open_area': get_int(value), 'audience': get_audience(value)
}.get(field_name, str(value))
#---------------------------------------
#---------------------------------------
def get_cell_style(field_name):
font = xlwt.Font()
# Create the Font
font.name = 'Times New Roman'
default_style = xlwt.XFStyle()
# Create the Style
default_style.font = font
return {
}.get(field_name, default_style)
#------------------------------------------
#------------------------------------------
sorted_names = [u'id', 'name', 'data_begin', 'data_end', 'main_title', 'description', 'country', 'city']
cols_width = {'id': 1500, 'name':8000}
#field_setting.get('width', 20)
def sort_by_names(val):
try:
# put element on the index of sorted names
return sorted_names.index(val)
except ValueError:
# put element on the end
return len(sorted_names)

@ -0,0 +1,175 @@
# -*- coding: utf-8 -*-
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.decorators import login_required
#
import xlwt
import xlrd
import tempfile
#
from custom_forms import ImportEventForm, ExportEventForm
from excel_settings import sort_by_names, get_cell_style, get_cell
from excel_settings import cols_width
@login_required
def import_event(request):
if request.POST:
form = ImportEventForm(request.POST, request.FILES)
temp_file = tempfile.TemporaryFile()
import_file = request.FILES.get(request.FILES.keys()[0])
book = xlrd.open_workbook(file_contents=import_file)
sheet = book.sheet_by_index(0)
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
return HttpResponse(row_list[0])
else:
form = ImportEventForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('import_event.html', args)
def xls_to_response(xls, fname):
response = HttpResponse(mimetype="application/ms-excel")
response['Content-Disposition'] = 'attachment; filename=%s' % fname
xls.save(response)
return response
import datetime
from excel_settings import field_settings
from django.db.models.loading import get_model
def export_event(request):
if request.POST:
form = ExportEventForm(request.POST)
if form.is_valid():
data = form.cleaned_data
# get model
model = get_model(data['event'].split('.')[0], data['event'].split('.')[1])
# get objects
objects = model.objects.language(data['language']).filter(data_begin__range=[data['date_from'], data['date_to']],
country__in=data['country'],
theme__in=data['theme']
).distinct()
if not objects:
# not found any objects
message = 'По даному запросу объектов не найдено'
args = {}
args.update(csrf(request))
args['message'] = message
args['form'] = form
return render_to_response('export_event.html', args)
workbook = xlwt.Workbook(encoding = 'utf8')
# new tab
worksheet = workbook.add_sheet('My Worksheet')
# Create the Font for first rows
font = xlwt.Font()
font.name = 'Times New Roman'
font.bold = True
style = xlwt.XFStyle()
# Create the Style
style.font = font
for row, object in enumerate(objects):
for col, field in enumerate(field_settings):
try:
value = getattr(object, field['name'])
except AttributeError:
continue
if row == 0:
# first iteration. set names. set columns width
worksheet.write(0, col, field.get('verbose_name', 'default'), style)
worksheet.write(1, col, field.get('name'), style)
worksheet.col(col).width = field.get('width', 3333)
worksheet.write(row+2, col, field.get('type', str)(value))
return xls_to_response(workbook, 'My Worksheet.xls')
else:
form = ExportEventForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('export_event.html', args)
"""
def export_event(request):
if request.POST:
form = ExportEventForm(request.POST)
if form.is_valid():
# dict of objects
objects = form.generate_dicts()
return HttpResponse(str(objects))
if not objects:
# empty dict
message = 'По даному запросу объектов не найдено'
args = {}
args.update(csrf(request))
args['message'] = message
args['form'] = form
return render_to_response('export_event.html', args)
workbook = xlwt.Workbook(encoding = 'utf8')
# new tab
worksheet = workbook.add_sheet('My Worksheet')
# Create the Font
font = xlwt.Font()
font.name = 'Times New Roman'
font.bold = True
style = xlwt.XFStyle()
# Create the Style
style.font = font
# get names of fields sorted like in sorted_names list
fields = sorted(objects[0].keys(), key=sort_by_names)
# generate first row with verbose names
for i, field in enumerate(fields):
worksheet.write(0, i, objects[0][field]['verbose_name'], style)
# generate second row and set columns width
for i, field in enumerate(fields):
worksheet.write(1, i,field, style)
if field in cols_width:
worksheet.col(i).width = cols_width.get(field, 3333)
# fill row with objects
for row, object in enumerate(objects):
for key, value in object.iteritems():
# current row
col = fields.index(key)
# begins from third row
# get cell formats value (True -> 1, None -> '', ...)
worksheet.write(row+2, col, get_cell(key, value['value']), get_cell_style(key))
return xls_to_response(workbook, 'My Worksheet.xls')
else:
form = ExportEventForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('export_event.html', args)
"""

@ -4,6 +4,8 @@ from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^$', 'proj.views.home', name='home'),
url(r'^import-event/$', 'import_xls.views.import_event'),
url(r'^export-event/$', 'import_xls.views.export_event'),
url(r'^accounts/', include('registration.backends.default.urls')),
url(r'^accounts/', include('accounts.urls')),
url(r'^article/', include('article.urls')),

@ -157,6 +157,7 @@ TEMPLATE_DIRS = (
'/home/kotzilla/Documents/qwer/proj/templates/admin/conference',
'/home/kotzilla/Documents/qwer/proj/templates/admin/directories',
'/home/kotzilla/Documents/qwer/proj/templates/admin/exposition',
'/home/kotzilla/Documents/qwer/proj/templates/admin/import templates',
'/home/kotzilla/Documents/qwer/proj/templates/admin/news',
'/home/kotzilla/Documents/qwer/proj/templates/admin/organiser',
'/home/kotzilla/Documents/qwer/proj/templates/admin/place_conference',

@ -0,0 +1,92 @@
{% extends 'base.html' %}
{% load static %}
{% block scripts %}
{# selects #}
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/>
<script src="{% static 'js/select/select2.js' %}"></script>
<script src="{% static 'custom_js/make_select.js' %}"></script>
{# datetimepicker #}
<link href="{% static 'js/datetimepicker/css/datetimepicker.css' %}" rel="stylesheet"/>
<script src="{% static 'js/datetimepicker/js/bootstrap-datetimepicker.js' %}"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#id_date_from').datetimepicker({
todayHighlight: true,
format : 'dd.mm.yyyy',
minView:2
});
$('#id_date_to').datetimepicker({
todayHighlight: true,
format : 'dd.mm.yyyy',
minView:2
});
});
</script>
{% endblock %}
{% block body %}
<form method="post" class="form-horizontal" enctype="multipart/form-data"> {% csrf_token %}
{# event #}
<div class="control-group {% if form.event.errors %}error{% endif %}">
<label class="control-label">{{ form.event.label }}:</label>
<div class="controls">
{{ form.event }}
<span class="help-inline">{{ form.event.errors }}</span>
</div>
</div>
{# language #}
<div class="control-group {% if form.language.errors %}error{% endif %}">
<label class="control-label">{{ form.language.label }}:</label>
<div class="controls">
{{ form.language }}
<span class="help-inline">{{ form.language.errors }}</span>
</div>
</div>
{# date_from #}
<div class="control-group {% if form.date_from.errors %}error{% endif %}">
<label class="control-label">{{ form.date_from.label }}:</label>
<div class="controls">
{{ form.date_from }}
<span class="help-inline">{{ form.date_from.errors }}</span>
</div>
</div>
{# date_to #}
<div class="control-group {% if form.date_to.errors %}error{% endif %}">
<label class="control-label">{{ form.date_to.label }}:</label>
<div class="controls">
{{ form.date_to }}
<span class="help-inline">{{ form.date_to.errors }}</span>
</div>
</div>
{# theme #}
<div class="control-group {% if form.theme.errors %}error{% endif %}">
<label class="control-label">{{ form.theme.label }}:</label>
<div class="controls">
{{ form.theme }}
<span class="help-inline">{{ form.theme.errors }}</span>
</div>
</div>
{# country #}
<div class="control-group {% if form.country.errors %}error{% endif %}">
<label class="control-label">{{ form.country.label }}:</label>
<div class="controls">
{{ form.country }}
<span class="help-inline">{{ form.country.errors }}</span>
</div>
</div>
<div class="controls">
<input class="btn btn-large btn-primary" type="submit" value="Экспорт">
<input class="btn btn-large" type="reset" value="Отмена">
</div>
</form>
{% if message %}
<div class="alert alert-error">
{{ message }}
</div>
{% endif %}
{% endblock %}

@ -0,0 +1,42 @@
{% extends 'base.html' %}
{% load static %}
{% block scripts %}
{% endblock %}
{% block body %}
<form method="post" class="form-horizontal" enctype="multipart/form-data"> {% csrf_token %}
{# excel_file #}
<div class="control-group {% if form.excel_file.errors %}error{% endif %}">
<label class="control-label">{{ form.excel_file.label }}:</label>
<div class="controls">
{{ form.excel_file }}
<span class="help-inline">{{ form.excel_file.errors }}</span>
</div>
</div>
{# event #}
<div class="control-group {% if form.event.errors %}error{% endif %}">
<label class="control-label">{{ form.event.label }}:</label>
<div class="controls">
{{ form.event }}
<span class="help-inline">{{ form.event.errors }}</span>
</div>
</div>
{# language #}
<div class="control-group {% if form.language.errors %}error{% endif %}">
<label class="control-label">{{ form.language.label }}:</label>
<div class="controls">
{{ form.language }}
<span class="help-inline">{{ form.language.errors }}</span>
</div>
</div>
<div class="controls">
<input class="btn btn-large btn-primary" type="submit" value="Импорт">
<input class="btn btn-large" type="reset" value="Отмена">
</div>
</form>
{% endblock %}

@ -101,8 +101,11 @@
<li><a href="/admin/exposition/all">Выставка</a></li>
<li><a href="/admin/conference/all">Конференция</a></li>
<li><a href="/admin/seminar/all">Семинар</a></li>
<li><a href="/admin/webinar/all">Вебинар</a></li>
<li class="divider"></li>
<li><a href="/admin/webinar/all">Вебинар</a></li>
<li><a href="/admin/import-event">Импорт</a></li>
<li><a href="/admin/export-event">Экспорт</a></li>
</ul>
</li>
@ -147,6 +150,7 @@
<li><a href="/admin/currency/add">Валюты</a></li>
</ul>
</li>
<li><a href="/accounts/register">Зарегестрировать<br> пользователя</a></li>
<li><a href="/admin/accounts/logout_admin"><i class="icon-share-alt"></i> Выйти</a></li>

@ -50,7 +50,7 @@ class Webinar(TranslatableModel):
tax = models.BooleanField(verbose_name='Налог', default=1)
min_price = models.PositiveIntegerField(verbose_name='Минимальная цена', blank=True, null=True)
max_price = models.PositiveIntegerField(verbose_name='Максимальная цена', blank=True, null=True)
##
#
#administrator can cancel webinar
canceled_by_administrator = models.BooleanField(default=0)
#can publish not immediately

Loading…
Cancel
Save