# -*- coding: utf-8 -*- import json import random from django.conf import settings from django.contrib import admin from django.contrib.auth.decorators import login_required from django.contrib.contenttypes.models import ContentType from django.core.context_processors import csrf from django.db import models from django.forms.formsets import BaseFormSet, 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.utils.translation import ugettext_lazy as _ from modeltranslation.admin import TabbedTranslationAdmin from sorl.thumbnail import get_thumbnail from sorl.thumbnail.admin.current import AdminImageWidget from exposition.admin import get_by_lang from city.models import City from file.forms import FileForm, FileModelForm from file.models import FileModel, TmpFile from forms import ( ConferenceChangeForm, ConferenceCreateForm, ConferenceDeleteForm, ConferenceFilterForm, StatisticForm, TimeTableForm ) from functions.admin_views import ( AdminListView, AdminView, stat_paginate_results, upload_photo ) from functions.custom_views import delete_object, objects_list from functions.views_help import get_referer from functions.admin import DefaultAdmin from haystack.query import SearchQuerySet from models import Conference, Statistic, TimeTable, Speaker from photologue.forms import PhotoForm from theme.models import Tag class SpeakerAdmin(DefaultAdmin, TabbedTranslationAdmin): list_display = ['fullname', 'company', 'position', 'thumb'] formfield_overrides = { models.ImageField: {'widget': AdminImageWidget}, } class Media: css = {'all': ('client/css/jquery.fancybox.css', 'client/lib/fancybox/helpers/jquery.fancybox-thumbs.css')} js = ('client/js/jquery.mousewheel.min.js', 'client/lib/fancybox/jquery.fancybox.pack.js', 'client/lib/fancybox/helpers/jquery.fancybox-thumbs.js', 'client/js/admin_thumbs.js') def thumb(self, obj): thumbnail = get_thumbnail(obj.photo, '75x75', crop='center', quality=99) body = '\ img'.format( obj.photo.url, thumbnail.url, obj.id) return body thumb.short_description = _(u'превью') thumb.allow_tags = True admin.site.register(Speaker, SpeakerAdmin) def conference_all(request): """ Return list of all conferences with pagination """ return objects_list(request, Conference, 'conference_all.html') @login_required def conference_switch(request, url, action): """ turn on or off conference take: url as url of conference action as action what to do('on' or 'off') """ conference = Conference.objects.safe_get(url=url) if not conference: return HttpResponse('error') else: if action == 'on': conference.on() return HttpResponse('on') elif action == 'off': conference.off() return HttpResponse('off') else: return HttpResponse('error') @login_required def conference_copy(request, url): conference = Conference.objects.safe_get(url=url) if not conference: return HttpResponseRedirect(get_referer(request)) else: conference.clone() return HttpResponseRedirect(get_referer(request)) @login_required def conference_add(request): """ Returns form of conference and post it on the server. If form is posted redirect on the page of all conferences. """ # 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}) if request.POST: form = ConferenceCreateForm(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(): conference = 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.conference = conference statistic.save() return HttpResponseRedirect('/admin/conference/all/') else: form = ConferenceCreateForm(initial={'key': key}) formset_statistic = StatisticFormSet() args = {} args.update(csrf(request)) args['form'] = form args['languages'] = settings.LANGUAGES args['file_form'] = file_form args['files'] = TmpFile.objects.filter(key=key) args['formset_statistic'] = formset_statistic return render_to_response('conference_add.html', args) def conference_delete(request, url): return delete_object(request, Conference, ConferenceDeleteForm, url, '/admin/conference/all') @login_required def conference_change(request, url): """ Return form of conference and fill it with existing Conference object data. If form of conference is posted redirect on the page of all conferences. """ try: #check if conference_id exists else redirect to the list of conferences conference = Conference.objects.get(url=url) file_form = FileModelForm(initial={'model': 'city.City'}) except: return HttpResponseRedirect('/admin/conference/all/') if request.POST: StatisticFormSet = formset_factory(StatisticForm) form = ConferenceChangeForm(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(): conference = form.save(getattr(conference, 'id')) #delete old halls Statistic.objects.filter(conference=getattr(conference, '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.conference = conference statistic.save() return HttpResponseRedirect('/admin/conference/all/') else: #initial StatisticFormSet StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('conference',)) #fill form with data from database data = {'web_page':conference.web_page, 'place_alt': conference.place_alt, 'foundation_year': conference.foundation_year, 'data_begin':conference.data_begin, 'data_end':conference.data_end, 'currency':conference.currency, 'tax':conference.tax, 'min_price':conference.min_price, 'max_price':conference.max_price, 'link':conference.link, 'conference_id':conference.id, 'expohit': conference.expohit, 'discount': conference.discount,'canceled': conference.canceled, 'moved': conference.moved, 'visitors': conference.visitors, 'members': conference.members, # 'quality_label': [item for item, bool in conference.quality_label if bool==True] } if conference.country: data['country'] = conference.country.id if conference.city: data['city'] = conference.city.id if conference.place: data['place'] = conference.place.id data['theme'] = [item.id for item in conference.theme.all()] data['tag'] = [item.id for item in conference.tag.all()] #data from translated fields for code, name in settings.LANGUAGES: obj = Conference._meta.translations_model.objects.get(language_code = code,master__id=getattr(conference, '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['main_themes_%s' % code] = obj.main_themes 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 = ConferenceChangeForm(initial=data) form.fields['city'].widget.attrs['data-init-text'] = conference.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(conference=getattr(conference, '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 #get list of files which connected with specific model object args['files'] = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(conference), object_id=getattr(conference, 'id')) args['obj_id'] = getattr(conference, 'id') return render_to_response('conference_add.html', args) class ConferenceView(AdminView): form_class = ConferenceCreateForm model = Conference success_url = '/admin/conference/all/' template_name = 'c_admin/conference/conference.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(ConferenceView, self).get_form(form_class) obj = self.set_obj() if obj: data = {'web_page':obj.web_page, 'place_alt':obj.place_alt, 'foundation_year': obj.foundation_year, 'data_begin':obj.data_begin, 'data_end':obj.data_end, 'currency':obj.currency, 'tax':obj.tax, 'min_price':obj.min_price, 'max_price':obj.max_price, 'link':obj.link, 'conference_id':obj.id, 'expohit': obj.expohit, 'periodic':obj.periodic, 'discount': obj.discount,'canceled': obj.canceled, 'moved': obj.moved, 'visitors': obj.visitors, 'members': obj.members, 'logo': obj.logo, 'audience': obj.audience.all().values_list('pk', flat=True), 'partner': obj.partner, 'org': obj.org, # 'quality_label': [item for item, bool in obj.quality_label if bool==True], } if obj.place: data['place'] = obj.place.id 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] = 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['main_themes_%s' % code] = trans_obj.main_themes data['discount_description_%s' % code] = trans_obj.discount_description 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(ConferenceView, self).get_context_data(**kwargs) obj = self.set_obj() if obj: context['stat_form'] = StatisticForm() context['file_form'] = FileForm(initial={'model': 'conference.Conference'}) files = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(obj),object_id=getattr(obj, 'id')) context['files'] = files context['photo_form'] = PhotoForm() context['timetable_form'] = TimeTableForm() context['timetables'] = TimeTable.objects.filter(conference=obj) return context class ConferenceListView(AdminListView): paginate_func = staticmethod(stat_paginate_results) template_name = 'c_admin/conference/conference_list.html' form_class = ConferenceFilterForm model = Conference def upload_conference_photo(request, conf_id): return upload_photo(request, conf_id, Conference) def search_conf(request): term = request.GET.get('term') lang = translation.get_language() qs = SearchQuerySet().models(Conference) 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 conf_copy(request): response = {'redirect': ''} conf = Conference.objects.get(id=request.GET['id']) duplicate = conf.copy(request.GET['url']) if isinstance(duplicate, Conference): response['redirect'] = '/admin/conference/%s/'%duplicate.url else: response['msg'] = duplicate return HttpResponse(json.dumps(response), content_type='application/json')