# -*- coding: utf-8 -*- import json import random from city.models import City from django.conf import settings from django.contrib.auth.decorators import login_required from django.contrib.contenttypes.models import ContentType from django.core.context_processors import csrf from django.forms.formsets import formset_factory from django.forms.models import modelformset_factory from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render_to_response from django.utils import translation from django.views.decorators.csrf import csrf_exempt from file.forms import FileModelForm from file.models import FileModel, TmpFile from forms import ( ExpositionCreateForm, ExpositionDeleteForm, ExpositionFilterForm, StatisticForm, TimeTableForm ) from functions.admin_views import ( AdminListView, AdminView, stat_paginate_results ) from functions.custom_views import delete_object, objects_list from functions.views_help import get_referer from haystack.query import SearchQuerySet from models import Exposition, Statistic, TimeTable, TmpTimeTable from photologue.admin import upload_photo from theme.models import Tag def exposition_all(request): """ Return list of all expositions with pagination """ return objects_list(request, Exposition, 'exposition_all.html') @login_required def exposition_switch(request, url, action): """ turn on or off exposition take: url as url of exposition action as action what to do('on' or 'off') """ exposition = Exposition.objects.safe_get(url=url) if not exposition: return HttpResponse('error') else: if action == 'on': exposition.on() return HttpResponse('on') elif action == 'off': exposition.off() return HttpResponse('off') else: return HttpResponse('error') @login_required def exposition_copy(request, url): exposition = Exposition.objects.safe_get(url=url) if not exposition: return HttpResponseRedirect(get_referer(request)) else: exposition.clone() return HttpResponseRedirect(get_referer(request)) @login_required def exposition_add(request): """ Returns form of exposition and post it on the server. If form is posted redirect on the page of all expositions. """ # formset of StatisticForm StatisticFormSet = formset_factory(StatisticForm) # if form would be not valid key must be same if request.POST.get('key'): key = request.POST['key'] else: key = random.getrandbits(128) file_form = FileModelForm(initial={'key': key}) timetable_form = TimeTableForm(initial={'key': key}) if request.POST: form = ExpositionCreateForm(request.POST) # set choices filled by ajax form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.all()] form.fields['city'].choices = [(item.id, item.name) for item in City.objects.filter(country=request.POST['country'])] formset_statistic = StatisticFormSet(request.POST) if form.is_valid() and formset_statistic.is_valid(): exposition = form.save() for item in formset_statistic.forms: # saves forms if its valid and not empty if item.is_valid() and item.has_changed(): statistic = item.save(commit=False) statistic.exposition = exposition statistic.save() return HttpResponseRedirect('/admin/exposition/all/') else: form = ExpositionCreateForm(initial={'key': key}) formset_statistic = StatisticFormSet() args = {} args.update(csrf(request)) args['form'] = form args['file_form'] = file_form args['files'] = TmpFile.objects.filter(key=key) args['timetables'] = TmpTimeTable.objects.filter(key=key) args['languages'] = settings.LANGUAGES args['formset_statistic'] = formset_statistic args['timetable_form'] = timetable_form return render_to_response('exposition_add.html', args) def exposition_delete(request, url): return delete_object(request, Exposition, ExpositionDeleteForm, url, '/admin/exposition/all') @login_required def exposition_change(request, url): """ Return form of exposition and fill it with existing Exposition object data. If form of exposition is posted redirect on the page of all expositions. """ try: # check if exposition_id exists else redirect to the list of expositions exposition = Exposition.objects.get(url=url) file_form = FileModelForm(initial={'model': 'exposition.Exposition'}) except: return HttpResponseRedirect('/admin/exposition/all/') if request.POST: StatisticFormSet = formset_factory(StatisticForm) form = ExpositionCreateForm(request.POST) # set choices filled by ajax form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.all()] form.fields['city'].choices = [(item.id, item.name) for item in City.objects.filter(country=request.POST['country'])] formset_statistic = StatisticFormSet(request.POST) if form.is_valid() and formset_statistic.is_valid(): exposition = form.save(getattr(exposition, 'id')) # delete old halls Statistic.objects.filter(exposition=getattr(exposition, 'id')).delete() for item in formset_statistic.forms: # saves new statistic if its valid and not empty if item.is_valid() and item.has_changed(): statistic = item.save(commit=False) statistic.exposition = exposition statistic.save() return HttpResponseRedirect('/admin/exposition/all/') else: # initial StatisticFormSet StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('exposition',)) # fill form with data from database data = {'web_page':exposition.web_page, 'foundation_year': exposition.foundation_year, 'data_begin':exposition.data_begin, 'data_end':exposition.data_end, 'periodic':exposition.periodic, 'min_area':exposition.min_area, 'currency':exposition.currency, 'tax':exposition.tax, 'price_day':exposition.price_day, 'price_all':exposition.price_all, 'price_catalog':exposition.price_catalog, 'price_day_bar':exposition.price_day_bar, 'price_all_bar':exposition.price_all_bar, 'min_closed_area':exposition.min_closed_area, 'max_closed_area':exposition.max_closed_area, 'min_closed_equipped_area':exposition.min_closed_equipped_area, 'max_closed_equipped_area':exposition.max_closed_equipped_area, 'min_stand_size':exposition.min_stand_size, 'application_deadline':exposition.application_deadline, 'min_open_area':exposition.min_open_area, 'max_open_area':exposition.max_open_area, 'registration_payment':exposition.registration_payment, 'exposition_id':exposition.id, 'expohit': exposition.expohit, 'discount': exposition.discount, 'canceled': exposition.canceled, 'moved': exposition.moved, 'visitors': exposition.visitors, 'members': exposition.members, 'audience':[item for item, bool in exposition.audience if bool==True], 'quality_label': [item for item, bool in exposition.quality_label if bool==True]} if exposition.country: data['country'] = exposition.country.id if exposition.city: data['city'] = exposition.city.id if exposition.place: data['place'] = exposition.place.id data['theme'] = [item.id for item in exposition.theme.all()] data['tag'] = [item.id for item in exposition.tag.all()] data['organiser'] = [item.id for item in exposition.organiser.all()] data['company'] = [item.id for item in exposition.company.all()] # data from translated fields for code, name in settings.LANGUAGES: obj = Exposition._meta.translations_model.objects.get(language_code = code,master__id=getattr(exposition, 'id')) #access to translated fields data['name_%s' % code] = obj.name data['description_%s' % code] = obj.description data['main_title_%s' % code] = obj.main_title data['time_%s' % code] = obj.time data['products_%s' % code] = obj.products data['discount_description_%s' % code] = obj.discount_description data['title_%s' % code] = obj.title data['keywords_%s' % code] = obj.keywords data['descriptions_%s' % code] = obj.descriptions # initial form form = ExpositionCreateForm(initial=data) form.fields['city'].widget.attrs['data-init-text'] = exposition.city.name # set choices filled by ajax #form.fields['city'].choices = [(item.id, item.name) for item in City.objects.filter(country=data['country'])] form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.filter(theme__in=data['theme'])] # get existing statistic statistic = Statistic.objects.filter(exposition=getattr(exposition, 'id')) # fill HallFormSet formset_statistic = StatisticFormSet(queryset=statistic) args = {} args.update(csrf(request)) args['form'] = form args['languages'] = settings.LANGUAGES args['file_form'] = file_form args['formset_statistic'] = formset_statistic args['timetable_form'] = TimeTableForm() args['timetables'] = TimeTable.objects.filter(exposition=exposition) # get list of files which connected with specific model object args['files'] = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(exposition), object_id=getattr(exposition, 'id')) args['obj_id'] = getattr(exposition, 'id') return render_to_response('exposition_add.html', args) class ExpositionView(AdminView): form_class = ExpositionCreateForm model = Exposition success_url = '/admin/exposition/all/' template_name = 'c_admin/exposition/exposition.html' def form_valid(self, form): self.set_obj() expo = form.save(obj=self.obj) return HttpResponseRedirect(self.success_url) def get_form(self, form_class): if self.request.POST: return super(ExpositionView, self).get_form(form_class) obj = self.set_obj() if obj: data = {'web_page':obj.web_page, 'foundation_year': obj.foundation_year, 'data_begin':obj.data_begin, 'data_end':obj.data_end, 'periodic':obj.periodic, 'min_area':obj.min_area, 'currency':obj.currency, 'tax':obj.tax, 'price_day':obj.price_day, 'price_all':obj.price_all, 'price_catalog':obj.price_catalog, 'price_day_bar':obj.price_day_bar, 'price_all_bar':obj.price_all_bar, 'min_closed_area':obj.min_closed_area, 'max_closed_area':obj.max_closed_area, 'min_closed_equipped_area':obj.min_closed_equipped_area, 'max_closed_equipped_area':obj.max_closed_equipped_area, 'min_stand_size':obj.min_stand_size, 'application_deadline':obj.application_deadline, 'min_open_area':obj.min_open_area, 'max_open_area':obj.max_open_area, 'registration_payment':obj.registration_payment, 'exposition_id':obj.id, 'registration_link': obj.registration_link, 'org': obj.org, 'expohit': obj.expohit, 'discount': obj.discount, 'canceled': obj.canceled, 'moved': obj.moved, 'logo': obj.logo, 'visitors': obj.visitors, 'members': obj.members, 'audience': [item for item in obj.audience.all()], 'quality_label': [item for item, bool in obj.quality_label if bool], 'place_alt': obj.place_alt} if obj.place: data['place'] = obj.place.id if obj.area: data['area'] = obj.area data['theme'] = [item.id for item in obj.theme.all()] data['tag'] = ','.join(['%s:%s'%(item.id, item.name) for item in obj.tag.all()]) data['organiser'] = [item.id for item in obj.organiser.all()] data['company'] = [item.id for item in obj.company.all()] data['country'] = obj.country_id data['city'] = obj.city_id for code, name in settings.LANGUAGES: trans_obj = self.model._meta.translations_model.objects.get(language_code = code,master__id=obj.id) #access to translated fields data['name_%s' % code] = trans_obj.name data['description_%s' % code] = trans_obj.description data['main_title_%s' % code] = trans_obj.main_title data['time_%s' % code] = trans_obj.time data['products_%s' % code] = trans_obj.products data['price_day_%s' % code] = trans_obj.price_day data['price_all_%s' % code] = trans_obj.price_all data['price_day_bar_%s' % code] = trans_obj.price_day_bar data['price_all_bar_%s' % code] = trans_obj.price_all_bar data['discount_description_%s' % code] = trans_obj.discount_description data['stat_countries_%s' % code] = trans_obj.stat_countries data['pre_condition_%s' % code] = trans_obj.pre_condition data['stand_condition_%s' % code] = trans_obj.stand_condition data['visit_note_%s' % code] = trans_obj.visit_note data['participation_note_%s' % code] = trans_obj.participation_note data['title_%s' % code] = trans_obj.title data['keywords_%s' % code] = trans_obj.keywords data['descriptions_%s' % code] = trans_obj.descriptions form = form_class(initial=data) form.fields['city'].widget.attrs['data-init-text'] = obj.city.name form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.language().filter(theme__in=data['theme'])] return form else: return form_class() def get_context_data(self, **kwargs): context = super(ExpositionView, self).get_context_data(**kwargs) obj = self.set_obj() if obj: context['stat_form'] = StatisticForm() context['timetable_form'] = TimeTableForm() context['timetables'] = TimeTable.objects.filter(exposition=obj) return context class ExpositionListView(AdminListView): paginate_func = staticmethod(stat_paginate_results) template_name = 'c_admin/exposition/exposition_list.html' form_class = ExpositionFilterForm model = Exposition @csrf_exempt def upload_exposition_photo(request, expo_id): return upload_photo(request, expo_id, Exposition) def get_by_lang(item, field, lang='en'): """ :param item: searchresult object field: translated field :return: """ return getattr(item, field+'_'+lang) def search_expo(request): term = request.GET.get('term') lang = translation.get_language() qs = SearchQuerySet().models(Exposition) if request.GET.get('subscribers'): qs = qs.filter(subscribers__gt=0) if not term: qs = qs.order_by('text')[:30] else: qs = qs.autocomplete(content_auto=term.capitalize()).order_by('text')[:30] result = [] for item in qs: label = get_by_lang(item, 'name', lang) if label: result.append({'id': item.pk, 'label': label}) return HttpResponse(json.dumps(result), content_type='application/json') def expo_copy(request): response = {'redirect': ''} expo = Exposition.objects.get(id=request.GET['id']) duplicate = expo.copy(request.GET['url']) if isinstance(duplicate, Exposition): response['redirect'] = '/admin/exposition/%s/'%duplicate.url else: response['msg'] = duplicate return HttpResponse(json.dumps(response), content_type='application/json')