diff --git a/README.md b/README.md index 0602e7d9..c93b2e37 100644 --- a/README.md +++ b/README.md @@ -53,3 +53,16 @@ python manage.py migrate accounts python manage.py migrate company 0001 --fake python manage.py migrate company ``` + + +# solr setup +curl -LO https://archive.apache.org/dist/lucene/solr/4.10.4/solr-4.10.4.tgz +tar -xzf solr-4.10.4.tgz +sudo mv solr-4.10.4 /opt/solr-4.10.4 +sudo ln -s /opt/solr-4.10.4 /opt/solr +sudo ln -s /opt/solr-4.10.4/example/solr /etc/solr +sudo cp schema.xml /opt/solr-4.10.4/example/solr/collection1/conf +sudo useradd -d /opt/solr -s /sbin/false solr +sudo chown solr:solr -R /opt/solr +cd /opt/solr-4.10.4 +bin/solr start -p 8983 diff --git a/expobanner/forms.py b/expobanner/forms.py index a5a12179..5c1c9fe1 100644 --- a/expobanner/forms.py +++ b/expobanner/forms.py @@ -1,11 +1,16 @@ # -*- coding: utf-8 -*- -from django import forms -from expobanner.models import URL, BannerGroup, Banner, Paid, Top, MainPage -from exposition.models import Exposition +import json + +from city.models import City +from ckeditor.widgets import CKEditorWidget from conference.models import Conference from country.models import Country -from ckeditor.widgets import CKEditorWidget -from theme.models import Theme, Tag +from django import forms +from django.utils import translation +from django.utils.translation import ugettext_lazy as _ +from expobanner.models import URL, Banner, BannerGroup, MainPage, Paid, Top +from exposition.models import Exposition +from theme.models import Tag, Theme class UrlCreateForm(forms.ModelForm): @@ -272,11 +277,55 @@ class TopCreateForm(forms.ModelForm): return expo -class TopUpdateForm(forms.ModelForm): +class FieldsetMixin(object): + def fieldsets(self, fieldsets=None): + meta = getattr(self, 'Meta', None) or getattr(self, '_meta', None) + _fieldsets = fieldsets or meta.fieldsets + if _fieldsets: + for fs in _fieldsets: + yield { + 'title': fs.get('title'), + 'class': fs.get('class'), + 'fields': (self[field] for field in fs.get('fields')) if fs.get('fields') else None, + 'fieldsets': (fieldset for fieldset in self.fieldsets(fieldsets=fs.get('fieldsets'))) if fs.get('fieldsets') else None, + } + + +class TopUpdateForm(forms.ModelForm, FieldsetMixin): + cities = forms.CharField(label=u'Город', widget=forms.HiddenInput() ,required=False) + verbose = u'Изменить выставку' class Meta: model = Top - fields = ['catalog', 'position', 'theme', 'country', 'fr', 'to'] + fields = ['catalog', 'position', 'theme', 'country', 'fr', 'to', 'months', 'cities'] + fieldsets = [ + {'title': '', + 'class': '', + 'fields': ['catalog', 'position', 'theme', 'country', 'fr', 'to']}, + {'title': _(u'Топ города'), + 'class': '', + 'fields': ['cities', 'months']} + ] + def __init__(self, *args, **kwargs): + super(TopUpdateForm, self).__init__(*args, **kwargs) + instance = getattr(self, 'instance', None) + if instance: + lang = translation.get_language() + self.fields['cities'].widget.attrs['data-init-text'] =\ + json.dumps([{'id': item.id, 'text': item.name} for item in list(instance.cities.filter(translations__language_code=lang))]) + + def clean_cities(self): + cities = self.cleaned_data.get('cities') + if cities: + res = [] + for id in cities.split(','): + try: + res.append(int(id)) + except ValueError: + continue + return City.objects.filter(id__in=res) + else: + return City.objects.none() def save(self, commit=True): top = super(TopUpdateForm, self).save(commit=False) @@ -284,19 +333,21 @@ class TopUpdateForm(forms.ModelForm): old_save_m2m = self.save_m2m def save_m2m(): - old_save_m2m() - # This is where we actually link the pizza with toppings - top.theme.clear() - for theme in self.cleaned_data['theme']: - top.theme.add(theme) - top.country.clear() - for country in self.cleaned_data['country']: - top.country.add(country) - + old_save_m2m() + # This is where we actually link the pizza with toppings + top.theme.clear() + for theme in self.cleaned_data['theme']: + top.theme.add(theme) + top.country.clear() + for country in self.cleaned_data['country']: + top.country.add(country) + top.cities.clear() + for city in self.cleaned_data['cities']: + top.cities.add(city) self.save_m2m = save_m2m if commit: top.save() self.save_m2m() - return top \ No newline at end of file + return top diff --git a/expobanner/migrations/0002_auto__add_field_top_months.py b/expobanner/migrations/0002_auto__add_field_top_months.py new file mode 100644 index 00000000..4e04f5c7 --- /dev/null +++ b/expobanner/migrations/0002_auto__add_field_top_months.py @@ -0,0 +1,502 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Top.months' + db.add_column(u'expobanner_top', 'months', + self.gf('functions.custom_fields.MonthMultiSelectField')(default=None, max_length=255, null=True, blank=True), + keep_default=False) + + # Adding M2M table for field cities on 'Top' + m2m_table_name = db.shorten_name(u'expobanner_top_cities') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('top', models.ForeignKey(orm[u'expobanner.top'], null=False)), + ('city', models.ForeignKey(orm[u'city.city'], null=False)) + )) + db.create_unique(m2m_table_name, ['top_id', 'city_id']) + + + def backwards(self, orm): + # Deleting field 'Top.months' + db.delete_column(u'expobanner_top', 'months') + + # Removing M2M table for field cities on 'Top' + db.delete_table(db.shorten_name(u'expobanner_top_cities')) + + + models = { + u'accounts.user': { + 'Meta': {'ordering': "['-rating']", 'object_name': 'User'}, + 'blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'company': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'users'", 'null': 'True', 'to': u"orm['company.Company']"}), + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'date_registered': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '255', 'db_index': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_admin': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'organiser': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['organiser.Organiser']", 'unique': 'True', 'null': 'True', 'on_delete': 'models.PROTECT', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'position': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'rating': ('django.db.models.fields.IntegerField', [], {'default': '100'}), + 'translator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user'", 'null': 'True', 'on_delete': 'models.PROTECT', 'to': u"orm['translator.Translator']", 'blank': 'True', 'unique': 'True'}), + 'url': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'blank': 'True'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) + }, + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'city.city': { + 'Meta': {'unique_together': '()', 'object_name': 'City', 'index_together': '()'}, + 'code_IATA': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['directories.Iata']", 'null': 'True', 'blank': 'True'}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cities'", 'null': 'True', 'on_delete': 'models.PROTECT', 'to': u"orm['country.Country']"}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'inflect': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'blank': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'old_url': ('django.db.models.fields.CharField', [], {'max_length': '55'}), + 'phone_code': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'population': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'services': ('django.db.models.fields.BigIntegerField', [], {'default': 'None'}), + 'url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}) + }, + u'company.company': { + 'Meta': {'ordering': "['-rating', 'id']", 'unique_together': '()', 'object_name': 'Company', 'index_together': '()'}, + 'address': ('functions.custom_fields.LocationField', [], {'blank': 'True'}), + 'blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'city': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'companies'", 'null': 'True', 'on_delete': 'models.PROTECT', 'to': u"orm['city.City']"}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'companies'", 'null': 'True', 'on_delete': 'models.PROTECT', 'to': u"orm['country.Country']"}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'created_company'", 'null': 'True', 'to': u"orm['accounts.User']"}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'facebook': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'fax': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'foundation': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'linkedin': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'phone': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'rating': ('django.db.models.fields.IntegerField', [], {'default': '100'}), + 'staff_number': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'tag': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'companies'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['theme.Tag']"}), + 'theme': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'companies'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['theme.Theme']"}), + 'twitter': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'url': ('django.db.models.fields.SlugField', [], {'max_length': '255'}), + 'vk': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'web_page': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'country.area': { + 'Meta': {'ordering': "['translations__name']", 'unique_together': '()', 'object_name': 'Area', 'index_together': '()'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'country.country': { + 'Meta': {'ordering': "['translations__name']", 'unique_together': '()', 'object_name': 'Country', 'index_together': '()'}, + 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['country.Area']"}), + 'big_cities': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'cities'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['city.City']"}), + 'capital': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'capital'", 'null': 'True', 'on_delete': 'models.PROTECT', 'to': u"orm['city.City']"}), + 'country_code': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'currency': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['directories.Currency']", 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'inflect': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'language': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['directories.Language']", 'null': 'True', 'blank': 'True'}), + 'latitude': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'blank': 'True'}), + 'longitude': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'old_url': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '55'}), + 'phone_code': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'population': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'services': ('django.db.models.fields.BigIntegerField', [], {'default': 'None'}), + 'teritory': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'time_delivery': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'timezone': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}) + }, + u'directories.currency': { + 'Meta': {'unique_together': '()', 'object_name': 'Currency', 'index_together': '()'}, + 'code': ('django.db.models.fields.CharField', [], {'max_length': '3'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'directories.iata': { + 'Meta': {'object_name': 'Iata'}, + 'airport': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'code': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + u'directories.language': { + 'Meta': {'unique_together': '()', 'object_name': 'Language', 'index_together': '()'}, + 'code': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'expobanner.banner': { + 'Meta': {'ordering': "['sort']", 'object_name': 'Banner'}, + 'alt': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'cookie': ('django.db.models.fields.CharField', [], {'default': "'expo_b_default_popup'", 'max_length': '30', 'null': 'True', 'blank': 'True'}), + 'country': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['country.Country']", 'null': 'True', 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'flash': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2016, 5, 1, 0, 0)'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'banners'", 'null': 'True', 'to': u"orm['expobanner.BannerGroup']"}), + 'html': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'img': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'link': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'often': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}), + 'paid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'popup': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'sort': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '500'}), + 'stat_pswd': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'theme': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['theme.Theme']", 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'to': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'urls': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'url_banners'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['expobanner.URL']"}) + }, + u'expobanner.bannergroup': { + 'Meta': {'ordering': "['name']", 'object_name': 'BannerGroup'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'height': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), + 'speed': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '2000'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}) + }, + u'expobanner.log': { + 'Meta': {'object_name': 'Log'}, + 'banner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'banner_logs'", 'to': u"orm['expobanner.Banner']"}), + 'datetime': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'group_logs'", 'null': 'True', 'to': u"orm['expobanner.BannerGroup']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'page': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'type': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0', 'max_length': '1'}), + 'urls': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'url_logs'", 'blank': 'True', 'to': u"orm['expobanner.URL']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'users'", 'null': 'True', 'to': u"orm['accounts.User']"}), + 'user_agent': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}) + }, + u'expobanner.logstat': { + 'Meta': {'ordering': "['-date']", 'object_name': 'LogStat'}, + 'banner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'banner_stat'", 'blank': 'True', 'to': u"orm['expobanner.Banner']"}), + 'click': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'date': ('django.db.models.fields.DateField', [], {}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'group_stat'", 'null': 'True', 'to': u"orm['expobanner.BannerGroup']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'unique_click': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'unique_view': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'urls': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'url_bloks'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['expobanner.URL']"}), + 'view': ('django.db.models.fields.PositiveIntegerField', [], {}) + }, + u'expobanner.mainpage': { + 'Meta': {'ordering': "['-public']", 'object_name': 'MainPage'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'link': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Banner']"}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'position': ('django.db.models.fields.PositiveIntegerField', [], {'default': '2', 'null': 'True', 'blank': 'True'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'stat_pswd': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + u'expobanner.paid': { + 'Meta': {'ordering': "['-public']", 'object_name': 'Paid'}, + 'catalog': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'paid_catalog'", 'to': u"orm['expobanner.Banner']"}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'official': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'paid_official'", 'to': u"orm['expobanner.Banner']"}), + 'organiser': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'participation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'paid_participation'", 'to': u"orm['expobanner.Banner']"}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'stat_pswd': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'tickets': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'paid_tickets'", 'to': u"orm['expobanner.Banner']"}) + }, + u'expobanner.paidstat': { + 'Meta': {'ordering': "['-date']", 'object_name': 'PaidStat'}, + 'catalog_clicks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'catalog_views': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'date': ('django.db.models.fields.DateField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'official_clicks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'page_views': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'paid': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Paid']"}), + 'participation_clicks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'price_views': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'tickets_clicks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + u'expobanner.top': { + 'Meta': {'ordering': "['position']", 'object_name': 'Top'}, + 'catalog': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'cities': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'top_in_set'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['city.City']"}), + 'country': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['country.Country']", 'null': 'True', 'blank': 'True'}), + 'excluded_cities': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['city.City']", 'null': 'True', 'blank': 'True'}), + 'excluded_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['theme.Tag']", 'null': 'True', 'blank': 'True'}), + 'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2016, 5, 1, 0, 0)'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'link': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Banner']"}), + 'months': ('functions.custom_fields.MonthMultiSelectField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'position': ('django.db.models.fields.PositiveIntegerField', [], {'default': '2', 'null': 'True', 'blank': 'True'}), + 'stat_pswd': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'theme': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['theme.Theme']", 'null': 'True', 'blank': 'True'}), + 'to': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + u'expobanner.topstat': { + 'Meta': {'object_name': 'TopStat'}, + 'city': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['city.City']", 'null': 'True', 'blank': 'True'}), + 'clicks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['country.Country']", 'null': 'True', 'blank': 'True'}), + 'date': ('django.db.models.fields.DateField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'tag': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['theme.Tag']", 'null': 'True', 'blank': 'True'}), + 'theme': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['theme.Theme']", 'null': 'True', 'blank': 'True'}), + 'views': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + u'expobanner.url': { + 'Meta': {'ordering': "['-created_at']", 'object_name': 'URL'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'regex': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'sites': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'site_urls'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['sites.Site']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '2048'}) + }, + u'file.filemodel': { + 'Meta': {'unique_together': '()', 'object_name': 'FileModel', 'index_together': '()'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']", 'null': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'file_path': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'file_type': ('functions.custom_fields.EnumField', [], {'default': "'PDF'", 'values': "('PDF', 'DOC', 'TXT', 'OTHER', 'JPG', 'BMP', 'PNG', 'GIF')", 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'img_height': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'img_width': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'purpose': ('functions.custom_fields.EnumField', [], {'default': "'photo'", 'values': "['photo', 'flat', 'logo', 'map', 'scheme teritory', 'diplom', 'preview', 'preview2']"}) + }, + u'organiser.organiser': { + 'Meta': {'unique_together': '()', 'object_name': 'Organiser', 'index_together': '()'}, + 'active': ('django.db.models.fields.NullBooleanField', [], {'default': '0', 'null': 'True', 'blank': 'True'}), + 'address': ('functions.custom_fields.LocationField', [], {'null': 'True', 'blank': 'True'}), + 'city': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['city.City']", 'null': 'True', 'on_delete': 'models.PROTECT', 'blank': 'True'}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['country.Country']", 'null': 'True', 'on_delete': 'models.PROTECT', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'events_number': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'facebook': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'fax': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'foundation': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'linkedin': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'phone': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'place_conference': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'organiser_place_conference'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['place_conference.PlaceConference']"}), + 'place_exposition': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'organiser_place_exposition'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['place_exposition.PlaceExposition']"}), + 'rating': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'staff_number': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'tag': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['theme.Tag']", 'null': 'True', 'blank': 'True'}), + 'theme': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['theme.Theme']", 'null': 'True', 'blank': 'True'}), + 'twitter': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'url': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'blank': 'True'}), + 'vk': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'web_page': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) + }, + u'photologue.gallery': { + 'Meta': {'ordering': "['-date_added']", 'unique_together': '()', 'object_name': 'Gallery', 'index_together': '()'}, + 'date_added': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'photos': ('sortedm2m.fields.SortedManyToManyField', [], {'blank': 'True', 'related_name': "'galleries'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['photologue.Photo']"}), + 'sites': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['sites.Site']", 'null': 'True', 'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '200'}), + 'tags': ('photologue.models.TagField', [], {'max_length': '255', 'blank': 'True'}) + }, + u'photologue.photo': { + 'Meta': {'ordering': "['sort']", 'unique_together': '()', 'object_name': 'Photo', 'index_together': '()'}, + 'crop_from': ('django.db.models.fields.CharField', [], {'default': "'center'", 'max_length': '10', 'blank': 'True'}), + 'date_added': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'date_taken': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'effect': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'photo_related'", 'null': 'True', 'to': u"orm['photologue.PhotoEffect']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'sites': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['sites.Site']", 'null': 'True', 'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '200'}), + 'sort': ('django.db.models.fields.PositiveIntegerField', [], {'default': '10', 'null': 'True', 'db_index': 'True'}), + 'tags': ('photologue.models.TagField', [], {'max_length': '255', 'blank': 'True'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['photologue.UserMark']", 'null': 'True', 'symmetrical': 'False'}), + 'view_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + u'photologue.photoeffect': { + 'Meta': {'object_name': 'PhotoEffect'}, + 'background_color': ('django.db.models.fields.CharField', [], {'default': "'#FFFFFF'", 'max_length': '7'}), + 'brightness': ('django.db.models.fields.FloatField', [], {'default': '1.0'}), + 'color': ('django.db.models.fields.FloatField', [], {'default': '1.0'}), + 'contrast': ('django.db.models.fields.FloatField', [], {'default': '1.0'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'filters': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}), + 'reflection_size': ('django.db.models.fields.FloatField', [], {'default': '0'}), + 'reflection_strength': ('django.db.models.fields.FloatField', [], {'default': '0.6'}), + 'sharpness': ('django.db.models.fields.FloatField', [], {'default': '1.0'}), + 'transpose_method': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}) + }, + u'photologue.usermark': { + 'Meta': {'object_name': 'UserMark'}, + 'height': ('django.db.models.fields.PositiveSmallIntegerField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'left': ('django.db.models.fields.PositiveSmallIntegerField', [], {}), + 'top': ('django.db.models.fields.PositiveSmallIntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'marks'", 'to': u"orm['accounts.User']"}), + 'width': ('django.db.models.fields.PositiveSmallIntegerField', [], {}) + }, + u'place_conference.placeconference': { + 'Meta': {'unique_together': '()', 'object_name': 'PlaceConference', 'index_together': '()'}, + 'address': ('functions.custom_fields.LocationField', [], {}), + 'amount_halls': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'banquet_hall': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'catering': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'city': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'place_conferences'", 'on_delete': 'models.PROTECT', 'to': u"orm['city.City']"}), + 'conference_call': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['country.Country']", 'on_delete': 'models.PROTECT'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'exp_hall_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'exposition_hall': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'fax': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'foundation_year': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'hotel': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'blank': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'multimedia_equipment': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'phone': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'total_capacity': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'translate_equipment': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'type': ('functions.custom_fields.EnumField', [], {'default': "'Convention centre'", 'values': "['Convention centre', 'Exposition centre']"}), + 'url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), + 'video_link': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'views': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'virtual_tour': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'web_page': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'wifi': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}) + }, + u'place_exposition.placeexposition': { + 'Meta': {'ordering': "['-rating', 'id']", 'unique_together': '()', 'object_name': 'PlaceExposition', 'index_together': '()'}, + 'address': ('functions.custom_fields.LocationField', [], {}), + 'bank': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'business_centre': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'cafe': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'children_room': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'city': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'place_expositions'", 'on_delete': 'models.PROTECT', 'to': u"orm['city.City']"}), + 'closed_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'conference_centre': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['country.Country']", 'on_delete': 'models.PROTECT'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'disabled_service': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'event_in_year': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'fax': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'foundation_year': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_published': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '255', 'blank': 'True'}), + 'mobile_application': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'online_registration': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'open_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'parking': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'partner': ('django.db.models.fields.NullBooleanField', [], {'default': '0', 'null': 'True', 'blank': 'True'}), + 'phone': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'photogallery': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['photologue.Gallery']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'press_centre': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'rating': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'terminals': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'total_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'total_halls': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'total_pavilions': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'type': ('functions.custom_fields.EnumField', [], {'default': "'Exposition complex'", 'values': "['Exposition complex', 'Convention centre', 'Exposition centre']"}), + 'url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), + 'views': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'virtual_tour': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'web_page': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), + 'wifi': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}) + }, + u'sites.site': { + 'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"}, + 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'theme.tag': { + 'Meta': {'unique_together': '()', 'object_name': 'Tag', 'index_together': '()'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'inflect': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'old_url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), + 'theme': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tags'", 'on_delete': 'models.PROTECT', 'to': u"orm['theme.Theme']"}), + 'url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}) + }, + u'theme.theme': { + 'Meta': {'unique_together': '()', 'object_name': 'Theme', 'index_together': '()'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'inflect': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'main_page': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'db_index': 'True'}), + 'old_url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), + 'types': ('django.db.models.fields.BigIntegerField', [], {'default': 'None'}), + 'url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}) + }, + u'translator.translator': { + 'Meta': {'unique_together': '()', 'object_name': 'Translator', 'index_together': '()'}, + 'birth': ('django.db.models.fields.DateField', [], {}), + 'car': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'gender': ('functions.custom_fields.EnumField', [], {'default': "'male'", 'values': "('male', 'female')"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + } + } + + complete_apps = ['expobanner'] \ No newline at end of file diff --git a/expobanner/models.py b/expobanner/models.py index a9b98d70..600abe48 100644 --- a/expobanner/models.py +++ b/expobanner/models.py @@ -1,18 +1,20 @@ # -*- coding: utf-8 -*- -import random import hashlib -from datetime import datetime, date -from django.db import models -from django.utils.translation import ugettext_lazy as _ +import random +from collections import namedtuple +from datetime import date, datetime + +from country.models import Country from django.conf import settings from django.contrib.sites.models import Site +from django.db import models from django.db.models.signals import post_save -from .managers import BiasedManager, BannerGroupCached, URLCached, TopCached -from .mixins import StatMixin +from django.utils.translation import ugettext_lazy as _ +from functions.custom_fields import MonthMultiSelectField from theme.models import Theme -from country.models import Country -# from multiselectfield import MultiSelectField -# from functions.custom_fields import MonthMultiSelectField + +from .managers import BannerGroupCached, BiasedManager, TopCached, URLCached +from .mixins import StatMixin class URL(models.Model): @@ -282,8 +284,8 @@ class Top(models.Model, StatMixin): theme = models.ManyToManyField('theme.Theme', blank=True, null=True, verbose_name=u'Тематики') excluded_tags = models.ManyToManyField('theme.Tag', blank=True, null=True, verbose_name=u'Исключить теги') country = models.ManyToManyField('country.Country', blank=True, null=True, verbose_name=u'Страны') - cities = models.ManyToManyField('city.City', related_name='top_in_set', blank=True, null=True, verbose_name=u'Города') - # months = MonthMultiSelectField(blank=True, null=True, default=None, max_length=255) + cities = models.ManyToManyField('city.City', related_name='top_in_set', blank=True, null=True, verbose_name=_(u'Города')) + months = MonthMultiSelectField(_(u'Топ месяцев'), blank=True, null=True, default=None, max_length=255,) excluded_cities = models.ManyToManyField('city.City', blank=True, null=True, verbose_name=u'Исключить города') fr = models.DateField(default=date.today(), verbose_name=u'Начало') to = models.DateField(blank=True, null=True, verbose_name=u'Конец') diff --git a/expobanner/utils.py b/expobanner/utils.py index f3e457cf..1fc4779a 100644 --- a/expobanner/utils.py +++ b/expobanner/utils.py @@ -123,15 +123,18 @@ def get_top_events(tops, params, request): theme = params.get('theme', []) city = params.get('city', '') tag = params.get('tag', '') + month = params.get('month', '') + year = request.GET.get('year', '') catalog_tops = [item for item in tops if item.catalog == catalog] good_tops = [] for top in catalog_tops: country_ids = [str(item.id) for item in top.country.all()] theme_ids = [str(item.id) for item in top.theme.all()] + city_ids = [str(item.id) for item in top.cities.all()] excluded_tags_ids = [str(item.id) for item in top.excluded_tags.all()] excluded_cities_ids = [str(item.id) for item in top.excluded_cities.all()] - if not country_ids and not theme_ids: + if not any([country_ids, theme_ids, city_ids]): # universal top good_tops.append(top) continue @@ -139,6 +142,12 @@ def get_top_events(tops, params, request): if country in country_ids and city not in excluded_cities_ids : good_tops.append(top) continue + # check city + if all([city, city in city_ids, not theme]): + if (month and not month in top.months) or (not month and year): + continue + good_tops.append(top) + continue # check theme if tag in excluded_tags_ids: continue @@ -156,4 +165,4 @@ def get_top_events(tops, params, request): if event: top.link.log(request, 1) events.append(event) - return events \ No newline at end of file + return events diff --git a/expobanner/views.py b/expobanner/views.py index 22333adf..b5eb5d65 100644 --- a/expobanner/views.py +++ b/expobanner/views.py @@ -96,9 +96,10 @@ def get_top(request): 'tag': request.GET.get('tag'), 'country': request.GET.get('country'), 'city': request.GET.get('city'), - 'catalog': request.GET.get('catalog')} + 'catalog': request.GET.get('catalog'), + 'month': request.GET.get('month')} tops = Top.cached.all() events = get_top_events(tops, params, request) context = {'objects': events} - return render_to_response('client/includes/exposition/expo_top.html', context, context_instance=RequestContext(request)) \ No newline at end of file + return render_to_response('client/includes/exposition/expo_top.html', context, context_instance=RequestContext(request)) diff --git a/exposition/views.py b/exposition/views.py index 2b1d5d75..9bdbc35b 100644 --- a/exposition/views.py +++ b/exposition/views.py @@ -389,14 +389,19 @@ class ExpoCatalog(JitterCacheMixin, MetadataMixin, ListView): 'nov': {'value': 11, 'name': _(u'Ноябрь')}, 'dec': {'value': 12, 'name': _(u'Декабрь')}} if month and monthes.get(month): qs = qs.filter(data_begin__month=monthes[month]['value']) + self.month = { + 'text': monthes[month]['name'], + 'slug': '{m}/{y}'.format(m=monthes[month]['value'], y=year) + } if self.country: - self.month = {'text': monthes[month]['name'], 'link': '%s%s/country/%s/%s/%s/'% - (self.catalog_url, self.filter_object.url, self.country.url, year, month)} + self.month['link'] = '%s%s/country/%s/%s/%s/' %\ + (self.catalog_url, self.filter_object.url, self.country.url, year, month) elif self.city: - self.month = {'text': monthes[month]['name'], 'link': '%s%s/city/%s/%s/%s/'% - (self.catalog_url, self.filter_object.url, self.city.url, year, month)} + self.month['link'] = '%s%s/city/%s/%s/%s/' %\ + (self.catalog_url, self.filter_object.url, self.city.url, year, month) else: - self.month = {'text': monthes[month]['name'], 'link': '%s%s/%s/%s/'%(self.catalog_url, self.filter_object.url, year, month)} + self.month['link'] = '%s%s/%s/%s/' %\ + (self.catalog_url, self.filter_object.url, year, month) return qs.order_by('data_begin') @@ -624,4 +629,4 @@ def send_to_organiser(request, slug): msg.send() redirect_to = '%sservice/thanks/'%exposition.get_permanent_url() - return HttpResponse(json.dumps({'success':True, 'redirect_to': redirect_to}), content_type='application/json') \ No newline at end of file + return HttpResponse(json.dumps({'success':True, 'redirect_to': redirect_to}), content_type='application/json') diff --git a/functions/custom_fields.py b/functions/custom_fields.py index 9fc52a09..5fa4f1cb 100644 --- a/functions/custom_fields.py +++ b/functions/custom_fields.py @@ -1,10 +1,17 @@ # -*- coding: utf-8 -*- + +import re +from calendar import TimeEncoding, month_name +from datetime import date + from django import forms from django.conf import settings -from django.core import exceptions +from django.core import exceptions, validators from django.core.serializers.json import DjangoJSONEncoder from django.db import models from django.utils.safestring import mark_safe +from django.utils.text import capfirst +from django.utils.translation import ugettext_lazy as _ from south.modelsinspector import add_introspection_rules try: @@ -227,6 +234,162 @@ class LocationField(JSONField): return super(LocationField, self).formfield(**defaults) +_regex_validator = validators.RegexValidator( + regex=re.compile('^\[(u(\'|\")([1-9]|1[0-2])/[0-9]{4}(\'|\"),?\s?)+\]$')) + + +class MonthMultiSelectField(models.CharField): + __metaclass__ = models.SubfieldBase + _saved_month_names = None + _saved_choices_start_month = None + _saved_choices_start_year = None + _saved_choices = None + _saved_choices_values = None + _inst_saved_choices = set() + _inst_saved_choices_values = set() + + def __init__(self, *args, **kwargs): + # FIXME: need to reset if choices are given + # _saved_choices + # _saved_choices_values + # _saved_choices_month + choices = kwargs.pop('choices', None) + self.value_type = kwargs.pop('value_type', None) + super(MonthMultiSelectField, self).__init__(*args, **kwargs) + + self.validators.append(_regex_validator) + if choices is None: + self._choices = self._make_choices() + + @property + def flatchoices(self): + return None + + @classmethod + def get_month_names(cls, month_num, locale=('ru_RU', 'UTF-8')): + '''Usage: + get_months_names(1, ('ru_RU', 'UTF-8')) + ''' + with TimeEncoding(locale) as encoding: + if not isinstance(cls._saved_month_names, list): + cls._saved_month_names = list(month_name) + return cls._saved_month_names[month_num].decode(encoding) + + @classmethod + def make_choice_display(cls, m, y): + return _(u'%(month)s %(year)s') % {'month': cls.get_month_names(m), 'year': y} + + @staticmethod + def get_data_from_string(s): + pattern = re.compile('^(?P([1-9]|[1][0-2]))/(?P[0-9]{4})$') + m = p.match(s) + return m.group('month'), m.group('year') + + @classmethod + def get_month_from_string_display(cls, s): + return cls.make_choice_display(*self.get_month_from_string(s)) + + @classmethod + def _make_choice_map_func(cls, *args): + c = ('{m}/{y}'.format(m=args[0], y=args[1]), cls.make_choice_display(*args)) + cls._saved_choices_values.add(c[0]) + return c + + @classmethod + def _make_choices(cls): + today = date.today() + #years = [today.year, today.year + 1] # map(lambda x: today.year + x, xrange(0, 2)) + choices = [] + cls._saved_choices_values = set() + for year in [today.year, today.year + 1]: + year_choices = map( + lambda m: cls._make_choice_map_func(m, year), + xrange(today.month if year == today.year else 1, 13) + ) + choices.append((year, year_choices)) + return choices + + @property + def flatchoices(self): + return None + + def get_choices_default(self): + return self.get_choices(include_blank=False) + + def value_to_string(self, obj): + value = self._get_val_from_obj(obj) + return self.get_prep_value(value) + + def validate(self, value, model_instance): + if not self.editable: + # Skip validation for non-editable fields. + return + for opt_select in value: + if not self.valid_value(opt_select): + if django.VERSION[0] >= 1 and django.VERSION[1] >= 6: + raise exceptions.ValidationError(self.error_messages['invalid_choice'] % {"value": value}) + else: + raise exceptions.ValidationError(self.error_messages['invalid_choice'] % value) + + def valid_value(self, value): + "Check to see if the provided value is a valid choice" + print(value) + if value in self._saved_choices_values: + return True + return False + + def formfield(self, **kwargs): + """ + Returns a django.forms.Field instance for this database Field. + """ + defaults = { + 'choices': self.get_choices_default(), + 'required': not self.blank, + 'label': capfirst(self.verbose_name), + 'help_text': self.help_text, + 'initial': self.get_default(), + 'validators': [_regex_validator], + } + defaults.update(kwargs) + return forms.MultipleChoiceField(**defaults) + + def get_prep_value(self, value): + if value in validators.EMPTY_VALUES: + return self.get_default() + return ",".join(value) + + def to_python(self, value): + if any([value is None, not value]): + return [] + else: + if isinstance(value, set): + value = sorted(list(value)) + value_list = value if isinstance(value, list) else value.split(',') + if self.value_type is not None: + value_list = map(self.value_type, value_list) + return value_list + + def contribute_to_class(self, cls, name): + super(MonthMultiSelectField, self).contribute_to_class(cls, name) + if self.choices: + def get_list(obj): + fieldname = name + choicedict = dict(self.choices) + display = [] + values = getattr(obj, fieldname) + if values: + display = map( + lambda x: self.get_month_from_string_display(x), + values) + return display + + def get_display(obj): + return ", ".join(get_list(obj)) + + setattr(cls, 'get_%s_list' % self.name, get_list) + setattr(cls, 'get_%s_display' % self.name, get_display) + + add_introspection_rules([ ( [EnumField], # Class(es) these apply to @@ -236,3 +399,5 @@ add_introspection_rules([ }, ), ], ["^functions\.custom_fields\.EnumField", "^functions\.custom_fields\.LocationField"]) + +add_introspection_rules([], ["^functions\.custom_fields\.MonthMultiSelectField"]) diff --git a/proj/views.py b/proj/views.py index da2a4ba3..10e246f3 100644 --- a/proj/views.py +++ b/proj/views.py @@ -41,8 +41,8 @@ def expo_context(request): cont = {'theme_search_form': ThemeSearch(), 'expo_catalog': Exposition.catalog, 'book_aid': settings.BOOKING_AID, 'blogs': Article.objects.main_page_blogs(), 'news_list': Article.objects.main_page_news(), 'sng_countries': settings.SNG_COUNTRIES, - 'seo_text': add_seo(request), 'announce_subscribe': SubscribeAssideForm() - } + 'seo_text': add_seo(request), 'announce_subscribe': SubscribeAssideForm(), + 'NO_EXTERNAL_JS': getattr(settings, 'NO_EXTERNAL_JS', False)} user = request.user if not user.is_anonymous() and not user.url: diff --git a/schema.xml b/schema.xml new file mode 100644 index 00000000..6aaf5410 --- /dev/null +++ b/schema.xml @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + text + + + + + diff --git a/static/client/html-cut/events_feed.html b/static/client/html-cut/events_feed.html index 8e473a64..36842b4a 100644 --- a/static/client/html-cut/events_feed.html +++ b/static/client/html-cut/events_feed.html @@ -284,14 +284,16 @@
- + {% if not NO_EXTERNAL_JS %} + + {% endif %}
diff --git a/static/client/html-cut/paid_exposition.html b/static/client/html-cut/paid_exposition.html index 9eb2d08e..0da36824 100644 --- a/static/client/html-cut/paid_exposition.html +++ b/static/client/html-cut/paid_exposition.html @@ -331,12 +331,11 @@
- - - - + {% if not NO_EXTERNAL_JS %} + + {% endif %} diff --git a/static/client/html-cut/subscribe.html b/static/client/html-cut/subscribe.html index 96eb7e8a..b94f2857 100644 --- a/static/client/html-cut/subscribe.html +++ b/static/client/html-cut/subscribe.html @@ -266,10 +266,11 @@
- - + {% if not NO_EXTERNAL_JS %} + + {% endif %}
@@ -884,14 +885,16 @@
  • - - - - + {% if not NO_EXTERNAL_JS %} + + + + + {% endif %}
  • diff --git a/templates/admin/expobanner/top_create.html b/templates/admin/expobanner/top_create.html index 648ea992..2cf52c05 100644 --- a/templates/admin/expobanner/top_create.html +++ b/templates/admin/expobanner/top_create.html @@ -1,10 +1,12 @@ {% extends 'base.html' %} {% load static %} +{% load i18n %} {% block scripts %} {# selects #} + + {% if not NO_EXTERNAL_JS %} + + + {% endif %} - \ No newline at end of file + diff --git a/templates/client/includes/banners/catalog_inner_2.html b/templates/client/includes/banners/catalog_inner_2.html index fd12557e..dff1a291 100644 --- a/templates/client/includes/banners/catalog_inner_2.html +++ b/templates/client/includes/banners/catalog_inner_2.html @@ -1,23 +1,25 @@
    - -
    \ No newline at end of file + {% if not NO_EXTERNAL_JS %} + + {% endif %} + diff --git a/templates/client/includes/banners/detail_inner.html b/templates/client/includes/banners/detail_inner.html index e28563bd..6206dc9e 100644 --- a/templates/client/includes/banners/detail_inner.html +++ b/templates/client/includes/banners/detail_inner.html @@ -1,22 +1,26 @@
    - -
    \ No newline at end of file + {% if not NO_EXTERNAL_JS %} + + + + {% endif %} + diff --git a/templates/client/includes/exposition/expo_list_paid.html b/templates/client/includes/exposition/expo_list_paid.html index 1b5fdd3e..8933ea3f 100644 --- a/templates/client/includes/exposition/expo_list_paid.html +++ b/templates/client/includes/exposition/expo_list_paid.html @@ -94,30 +94,33 @@ {% if forloop.counter == 8 %} - - + {% if not NO_EXTERNAL_JS %} + + + {% endif %} + {%endif %} {% endfor %} @@ -151,4 +154,4 @@ removeCalendarText:"{% trans 'Из расписания' %}" }); -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/client/includes/social_widjet.html b/templates/client/includes/social_widjet.html index b78ef258..d3f65da5 100644 --- a/templates/client/includes/social_widjet.html +++ b/templates/client/includes/social_widjet.html @@ -4,18 +4,22 @@
    - + {% if not NO_EXTERNAL_JS %} + + {% endif %} {% else %}
    - + {% if not NO_EXTERNAL_JS %} + + {% endif %}
    {% endif %}