diff --git a/comments/views.py b/comments/views.py index a0da8c74..75e0fbe6 100644 --- a/comments/views.py +++ b/comments/views.py @@ -2,6 +2,7 @@ from django.views.generic.edit import FormMixin +from functions.http import JsonResponse from .forms import CommentForm @@ -13,24 +14,27 @@ class CommentMixin(FormMixin): return self.get_form(form_class) def post(self, request, *args, **kwargs): + self.commentform = None + if request.method == 'POST' and request.is_ajax(): + self.commentform = self.get_comment_form() + if self.commentform.is_valid(): + self.save_comment() + return JsonResponse({'success': True}) + else: + return JsonResponse({'success': False, 'errors': self.commentform.errors}) return self.get(request, *args, **kwargs) - # self.commentform = self.get_comment_form() - # if self.commentform.is_valid(): - # comment = self.commentform.save(commit=False) - # comment.user_id = request.user.pk - # comment.content_object = self.object - # comment.ip = request.META['REMOTE_ADDR'] - # comment.save() - # return self.get(request, *args, **kwargs) + + def save_comment(self): + comment = self.commentform.save(commit=False) + comment.user_id = self.request.user.pk + comment.content_object = self.object + comment.ip = self.request.META['REMOTE_ADDR'] + comment.save() def get_context_data(self, **kwargs): context = super(CommentMixin, self).get_context_data(**kwargs) - commentform = self.get_comment_form() - if self.request.method == 'POST' and commentform.is_valid(): - comment = commentform.save(commit=False) - comment.user_id = self.request.user.pk - comment.content_object = self.object - comment.ip = self.request.META['REMOTE_ADDR'] - comment.save() - context['commentform'] = commentform + self.commentform = self.get_comment_form() + if self.request.method == 'POST' and self.commentform.is_valid(): + self.save_comment() + context['commentform'] = self.commentform return context diff --git a/emencia/django/newsletter/migrations/0016_auto__add_field_contact_from_events.py b/emencia/django/newsletter/migrations/0016_auto__add_field_contact_from_events.py new file mode 100644 index 00000000..daad553e --- /dev/null +++ b/emencia/django/newsletter/migrations/0016_auto__add_field_contact_from_events.py @@ -0,0 +1,772 @@ +# -*- 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 'Contact.from_events' + db.add_column(u'newsletter_contact', 'from_events', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + # Adding M2M table for field conferences on 'Contact' + m2m_table_name = db.shorten_name(u'newsletter_contact_conferences') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('contact', models.ForeignKey(orm[u'newsletter.contact'], null=False)), + ('conference', models.ForeignKey(orm[u'conference.conference'], null=False)) + )) + db.create_unique(m2m_table_name, ['contact_id', 'conference_id']) + + # Adding M2M table for field expositions on 'Contact' + m2m_table_name = db.shorten_name(u'newsletter_contact_expositions') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('contact', models.ForeignKey(orm[u'newsletter.contact'], null=False)), + ('exposition', models.ForeignKey(orm[u'exposition.exposition'], null=False)) + )) + db.create_unique(m2m_table_name, ['contact_id', 'exposition_id']) + + + def backwards(self, orm): + # Deleting field 'Contact.from_events' + db.delete_column(u'newsletter_contact', 'from_events') + + # Removing M2M table for field conferences on 'Contact' + db.delete_table(db.shorten_name(u'newsletter_contact_conferences')) + + # Removing M2M table for field expositions on 'Contact' + db.delete_table(db.shorten_name(u'newsletter_contact_expositions')) + + + 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'conference.conference': { + 'Meta': {'unique_together': '()', 'object_name': 'Conference', 'index_together': '()'}, + 'audience': ('django.db.models.fields.BigIntegerField', [], {'default': 'None'}), + 'bad_url': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'canceled_by_administrator': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'city': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'conference_city'", 'on_delete': 'models.PROTECT', 'to': u"orm['city.City']"}), + 'company': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'conference_companies'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['company.Company']"}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'conference_country'", 'on_delete': 'models.PROTECT', 'to': u"orm['country.Country']"}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'currency': ('functions.custom_fields.EnumField', [], {'default': "'RUB'", 'values': "('RUB', 'USD', 'EUR', 'RMB', 'GBP', 'AED', 'SGD', 'TRY', 'CZK', 'CHF', 'SEK', 'LKR', 'UAH', 'IDR', 'PLN', 'JPY')"}), + 'data_begin': ('django.db.models.fields.DateField', [], {'db_index': 'True'}), + 'data_end': ('django.db.models.fields.DateField', [], {}), + 'discount': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'expohit': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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': 'False', 'db_index': 'True'}), + 'link': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'main': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.MainPage']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'main_page': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'db_index': 'True'}), + 'max_price': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'members': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'members_choice': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'members_fc': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'min_price': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'moved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'old_url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), + 'org': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'organiser': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'conference_organisers'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['organiser.Organiser']"}), + 'paid_new': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Paid']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'periodic': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}), + 'periodic_once': ('django.db.models.fields.CharField', [], {'max_length': '10', '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'}), + 'place': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'conference_place'", 'null': 'True', 'on_delete': 'models.PROTECT', 'to': u"orm['place_conference.PlaceConference']"}), + 'place_alt': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'price_choice': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'price_choice_eur': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'price_eur': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'price_rub': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'programm_link': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'}), + 'quality_label': ('django.db.models.fields.BigIntegerField', [], {'default': 'None'}), + 'rating': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True'}), + 'services': ('django.db.models.fields.BigIntegerField', [], {'default': 'None'}), + 'speakers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['conference.Speaker']", 'null': 'True', 'blank': 'True'}), + 'tag': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'conference_tags'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['theme.Tag']"}), + 'tax': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'theme': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'conference_themes'", 'symmetrical': 'False', 'to': u"orm['theme.Theme']"}), + 'top': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Top']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'conference_users'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['accounts.User']"}), + 'views': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'visitors': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'visitors_choice': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'web_page': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) + }, + u'conference.speaker': { + 'Meta': {'object_name': 'Speaker'}, + 'company': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'company_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'company_ru': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'fullname': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'fullname_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'fullname_ru': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'position': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'position_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'position_ru': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', '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'}), + 'customer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Customer']", 'null': 'True', 'blank': 'True'}), + 'flash': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2016, 11, 18, 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.customer': { + 'Meta': {'ordering': "['name']", 'object_name': 'Customer'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 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'}), + 'kind': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1', 'db_index': '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'", 'null': 'True', '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.top': { + 'Meta': {'ordering': "['position']", 'object_name': 'Top'}, + 'base_catalog': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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, 11, 18, 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'}), + 'years': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}) + }, + 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'exposition.exposition': { + 'Meta': {'unique_together': '()', 'object_name': 'Exposition', 'index_together': '()'}, + 'application_deadline': ('django.db.models.fields.DateField', [], {'null': 'True'}), + 'area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'audience': ('django.db.models.fields.BigIntegerField', [], {'default': 'None'}), + 'bad_url': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'canceled_by_administrator': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'city': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'exposition_city'", 'on_delete': 'models.PROTECT', 'to': u"orm['city.City']"}), + 'company': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'exposition_companies'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['company.Company']"}), + 'country': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'exposition_country'", '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': "'exposition_creator'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['accounts.User']"}), + 'currency': ('functions.custom_fields.EnumField', [], {'default': "'RUB'", 'values': "('RUB', 'USD', 'EUR', 'RMB', 'GBP', 'AED', 'SGD', 'TRY', 'CZK', 'CHF', 'SEK', 'LKR', 'UAH', 'IDR', 'PLN', 'JPY')"}), + 'data_begin': ('django.db.models.fields.DateField', [], {'db_index': 'True'}), + 'data_end': ('django.db.models.fields.DateField', [], {}), + 'discount': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'expohit': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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': 'False', 'db_index': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'main': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.MainPage']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'main_page': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'db_index': 'True'}), + 'max_closed_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'max_closed_equipped_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'max_open_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'members': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'members_choice': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'min_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'min_closed_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'min_closed_equipped_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'min_open_area': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'min_stand_size': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'moved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'old_url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), + 'org': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'organiser': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'exposition_organisers'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['organiser.Organiser']"}), + 'paid_new': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Paid']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'periodic': ('django.db.models.fields.FloatField', [], {'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'}), + 'place': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'exposition_place'", 'null': 'True', 'on_delete': 'models.PROTECT', 'to': u"orm['place_exposition.PlaceExposition']"}), + 'place_alt': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'price_catalog': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'price_choice': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'price_choice_eur': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'price_eur': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'price_rub': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'quality_label': ('django.db.models.fields.BigIntegerField', [], {'default': 'None'}), + 'rating': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'registration_link': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'}), + 'registration_payment': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'services': ('django.db.models.fields.BigIntegerField', [], {'default': 'None'}), + 'tag': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'exposition_tags'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['theme.Tag']"}), + 'tax': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'theme': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'exposition_themes'", 'symmetrical': 'False', 'to': u"orm['theme.Theme']"}), + 'top': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Top']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}), + 'url': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'exposition_users'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['accounts.User']"}), + 'views': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'visitors': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'visitors_choice': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'web_page': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}) + }, + 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'newsletter.attachment': { + 'Meta': {'object_name': 'Attachment'}, + 'file_attachment': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'newsletter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['newsletter.Newsletter']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'newsletter.contact': { + 'Meta': {'ordering': "('-modification_date',)", 'object_name': 'Contact'}, + 'activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'activation_code': ('django.db.models.fields.CharField', [], {'default': "'8bd478110027d97a9b49456f372a518181dc66b1'", 'max_length': '40'}), + 'area': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['country.Area']", 'null': 'True', 'blank': 'True'}), + 'conferences': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['conference.Conference']", 'null': 'True', 'symmetrical': 'False'}), + 'content_articles': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'content_news': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'content_overview': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '255'}), + 'expositions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['exposition.Exposition']", 'null': 'True', 'symmetrical': 'False'}), + 'f_countries': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['country.Country']", 'null': 'True', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'foreign': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'from_events': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'from_users': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_mailing_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'modification_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'moscow': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'periodic': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}), + 'periodic_day': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '3'}), + 'r_cities': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['city.City']", 'null': 'True', 'blank': 'True'}), + 'russia': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'subscriber': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['theme.Tag']", 'null': 'True', 'blank': 'True'}), + 'tester': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'themes': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['theme.Theme']", 'null': 'True', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['accounts.User']", 'null': 'True'}), + 'valid': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + u'newsletter.contactmailingstatus': { + 'Meta': {'ordering': "('-creation_date',)", 'object_name': 'ContactMailingStatus'}, + 'ab': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['newsletter.Contact']"}), + 'creation_date': ('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['newsletter.Link']", 'null': 'True', 'blank': 'True'}), + 'newsletter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['newsletter.Newsletter']"}), + 'status': ('django.db.models.fields.IntegerField', [], {}) + }, + u'newsletter.contactsettings': { + 'Meta': {'object_name': 'ContactSettings'}, + 'area': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['country.Area']", 'null': 'True', 'blank': 'True'}), + 'city': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['city.City']", 'null': 'True', 'blank': 'True'}), + 'contact': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['newsletter.Contact']", 'unique': 'True'}), + 'country': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['country.Country']", 'null': 'True', 'blank': 'True'}), + 'exponent_practicum': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'organiser_practicum': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'periodic': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'theme': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['theme.Theme']", 'null': 'True', 'blank': 'True'}) + }, + u'newsletter.link': { + 'Meta': {'ordering': "('-creation_date',)", 'object_name': 'Link'}, + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'newsletter.mailinglist': { + 'Meta': {'ordering': "('-creation_date',)", 'object_name': 'MailingList'}, + 'announce': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'announce_public_day': ('django.db.models.fields.IntegerField', [], {'default': '2'}), + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'modification_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'subscribers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'mailinglist_subscriber'", 'symmetrical': 'False', 'to': u"orm['newsletter.Contact']"}), + 'theme_for_filter': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['theme.Theme']", 'null': 'True', 'blank': 'True'}), + 'unsubscribers': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'mailinglist_unsubscriber'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['newsletter.Contact']"}) + }, + u'newsletter.newsletter': { + 'Meta': {'ordering': "('-creation_date',)", 'object_name': 'Newsletter'}, + 'ab_final_choice': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'ab_final_stage': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'ab_first_stage': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'ab_testing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'content': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'content2': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'dailymail': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'header_reply': ('django.db.models.fields.CharField', [], {'default': "'Expomap'", 'max_length': '255'}), + 'header_sender': ('django.db.models.fields.CharField', [], {'default': "'Expomap'", 'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mailing_list': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['newsletter.MailingList']", 'null': 'True', 'blank': 'True'}), + 'modification_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'preheader': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'preheader2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'sending_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'server': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['newsletter.SMTPServer']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), + 'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'test_contacts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['newsletter.Contact']", 'null': 'True', 'blank': 'True'}), + 'theme_for_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['theme.Theme']", 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title2': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}) + }, + u'newsletter.newsletterrecommend': { + 'Meta': {'ordering': "('-creation_date',)", 'object_name': 'NewsletterRecommend'}, + 'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['conference.Conference']", 'null': 'True'}), + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'exposition': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['exposition.Exposition']", 'null': 'True'}), + 'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2016, 11, 18, 0, 0)'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'theme': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['theme.Theme']", 'null': 'True', 'symmetrical': 'False'}), + 'to': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + u'newsletter.popupcount': { + 'Meta': {'ordering': "['-date']", 'unique_together': "(('theme', 'date'),)", 'object_name': 'PopupCount'}, + 'cnt': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'date': ('django.db.models.fields.DateField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'theme': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['theme.Theme']", 'null': 'True'}) + }, + u'newsletter.smtpserver': { + 'Meta': {'object_name': 'SMTPServer'}, + 'headers': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'host': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mails_hour': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'port': ('django.db.models.fields.IntegerField', [], {'default': '25'}), + 'tls': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}) + }, + u'newsletter.workgroup': { + 'Meta': {'object_name': 'WorkGroup'}, + 'contacts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['newsletter.Contact']", 'null': 'True', 'blank': 'True'}), + 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mailinglists': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['newsletter.MailingList']", 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'newsletters': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['newsletter.Newsletter']", 'null': 'True', 'blank': 'True'}) + }, + u'note.note': { + 'Meta': {'object_name': 'Note'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']", 'null': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'text': ('django.db.models.fields.TextField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['accounts.User']"}) + }, + 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'}), + 'top': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Top']", 'null': 'True', 'on_delete': 'models.SET_NULL', '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'}), + 'top': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['expobanner.Top']", 'null': 'True', 'on_delete': 'models.SET_NULL', '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_conf': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'db_index': 'True'}), + 'main_page_expo': ('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 = ['newsletter'] \ No newline at end of file diff --git a/emencia/django/newsletter/models.py b/emencia/django/newsletter/models.py index 1b9b6407..c20ede48 100644 --- a/emencia/django/newsletter/models.py +++ b/emencia/django/newsletter/models.py @@ -151,6 +151,7 @@ class Contact(models.Model): ) activated = models.BooleanField(default=False) from_users = models.BooleanField(default=False) + from_events = models.BooleanField(default=False) moscow = models.BooleanField(_(u'Москва'), blank=True, default=True) russia = models.BooleanField(_(u'Россия'), blank=True, default=True) @@ -168,6 +169,9 @@ class Contact(models.Model): tags = models.ManyToManyField('theme.Tag', verbose_name=_(u'Теги'), blank=True, null=True) themes = models.ManyToManyField('theme.Theme', blank=True, null=True, verbose_name=_(u'Тематики')) + conferences = models.ManyToManyField('conference.Conference', verbose_name=_(u'Конференции'), null=True) + expositions = models.ManyToManyField('exposition.Exposition', verbose_name=_(u'Выставки'), null=True) + content_type = models.ForeignKey(ContentType, blank=True, null=True) object_id = models.PositiveIntegerField(blank=True, null=True) content_object = generic.GenericForeignKey('content_type', 'object_id') diff --git a/events/urls.py b/events/urls.py index 548e156c..88d35ae9 100644 --- a/events/urls.py +++ b/events/urls.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- from django.conf.urls import include, patterns, url -from .views import FilterListView - +from .views import FilterListView, SubscribeView urlpatterns = patterns('', url(r'^$', FilterListView.as_view(), name='main'), url(r'^results/$', FilterListView.as_view(), {'with_form': False}, name='results'), url(r'^form/$', FilterListView.as_view(), {'with_results': False}, name='form'), + url(r'^subscribe/(?P(conf|expo))/(?P[^/]*)/$', SubscribeView.as_view(), name='subscribe'), ) diff --git a/events/views.py b/events/views.py index aee1c73f..6adf8e0f 100644 --- a/events/views.py +++ b/events/views.py @@ -1,11 +1,18 @@ # -*- coding: utf-8 -*- -from django.views.generic.edit import FormMixin +from django.core.exceptions import ObjectDoesNotExist +from django.db.models import Q +from django.http import Http404 +from django.http import HttpResponseForbidden +from django.http import HttpResponseNotFound +from django.views.generic.edit import FormMixin, FormView from django.conf import settings from django.template.loader import render_to_string from django.template import RequestContext from haystack.query import SearchQuerySet +from emencia.django.newsletter.forms import ContactForm +from emencia.django.newsletter.models import Contact from functions.custom_views import ContextMixin from functions.custom_views import ReverseOrderMixin from functions.custom_views import ListView @@ -78,3 +85,69 @@ class FilterListView_(ContextMixin, FormMixin, ListView): class FilterListView(ReverseOrderMixin, FilterListView_): pass + + +class SubscribeView(FormView): + form_class = ContactForm + template_name = None + models = {'expo': (Exposition, 'expositions'), 'conf': (Conference, 'conferences')} + defaults = { + 'activated': True, + 'from_events': True, + 'subscriber': False, + } + + def get_event(self): + model, self.attr = self.models.get(self.kwargs.get('model')) + slug = self.kwargs.get('slug') + return model.objects.get(url=slug) + + def set_event(self): + attr = getattr(self.contact, self.attr) + attr.add(self.event) + + def get_contact(self): + user = self.request.user + defaults = { + 'first_name': user.first_name, + 'last_name': user.last_name, + 'email': user.email, + 'user': user, + } + defaults.update(self.defaults) + try: + contact = Contact.objects.filter(Q(user=user) | Q(email=user.email))[0] + except (Contact.DoesNotExist, IndexError): + contact = Contact(defaults) + contact.save() + return contact + + def dispatch(self, request, *args, **kwargs): + if not request.is_ajax(): + return HttpResponseForbidden() + self.attr = None + self.contact = None + try: + self.event = self.get_event() + except ObjectDoesNotExist: + return HttpResponseNotFound() + return super(SubscribeView, self).dispatch(request, *args, **kwargs) + + def form_invalid(self, form): + return JsonResponse(form.errors, status=400) + + def form_valid(self, form): + contact = form.save(commit=False) + + contact.send_activation() + return self.success_responce() + + def success_responce(self): + self.set_event() + return JsonResponse({'success': True}) + + def post(self, request, *args, **kwargs): + if request.user.is_authenticated(): + self.contact = self.get_contact() + return self.success_responce() + return super(SubscribeView, self).post(request, *args, **kwargs) diff --git a/functions/model_mixin.py b/functions/model_mixin.py index f14b78e4..93774ac4 100644 --- a/functions/model_mixin.py +++ b/functions/model_mixin.py @@ -105,6 +105,7 @@ class EventMixin(object): 'country': self.country.name if self.country else '', 'city': self.city.name if self.city else '', 'place': self.get_event_place_name(), + 'place_url': self.place.url if self.place else None, 'theme': theme_name, 'tags': ', '.join([t.name for t in self.tag.language().all()]), 'booking_url': booking_url, diff --git a/proj/urls.py b/proj/urls.py index 25476d95..550046e2 100644 --- a/proj/urls.py +++ b/proj/urls.py @@ -80,7 +80,7 @@ urlpatterns += solid_i18n_patterns('', #url(r'^translators/', include('translator.urls')), url(r'^translators/', include('specialist_catalog.urls')), url(r'^newsletters/', include('emencia.django.newsletter.urls')), - url(r'^filter/', include('events.urls', namespace='events')), + url(r'^events/', include('events.urls', namespace='events')), url(r'^', include('accounts.urls')), url(r'^', include('exposition.urls')), url(r'^', include('settings.conference_old_urls')), # conference redirects from old version diff --git a/static/modeltranslation/css/tabbed_translation_fields.css b/static/modeltranslation/css/tabbed_translation_fields.css new file mode 100755 index 00000000..d21fe7d4 --- /dev/null +++ b/static/modeltranslation/css/tabbed_translation_fields.css @@ -0,0 +1,94 @@ +/* +* jQuery UI CSS Framework +* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +* http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/base/jquery.ui.core.css +*/ + +/* +backward compatibility: +.ui-tabs-selected: jquery ui < 1.10 +.ui-tabs-active classes jquery ui >= 1.10 +*/ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } +.ui-state-disabled { cursor: default !important; } +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } +/* http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/base/jquery.ui.tabs.css */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active, .ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { + position: absolute; + display: none; +} + +/* custom tabs theme */ +.ui-tabs { padding: 0; } +.ui-tabs .ui-tabs-nav { padding: 5px 0 0 10px; border-bottom: 1px solid #EEEEEE; } +.ui-tabs .ui-tabs-nav li { margin: 0; } +.ui-tabs .ui-tabs-nav li.required { font-weight: bold; } +.ui-tabs .ui-tabs-nav li a { + border: 1px solid #CCCCCC; + background: #eeeeee repeat-x; + border-bottom-width: 0; + color: #666666; + padding: 4px 10px 4px 10px; + margin-top: 2px; + -moz-border-radius-topright: 4px; + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topleft: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + font-size: 12px; +} + +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-tabs-selected a { + background: #7CA0C7 repeat-x; + color: #fff; + padding: 6px 10px 4px 10px; + margin-top: 0; +} + +.ui-tabs .ui-tabs-panel { + padding: 0; +} + +.inline-group .tabular .ui-tabs .ui-tabs-panel { + padding: 5px; +} +.inline-group .tabular .ui-tabs .ui-tabs-nav { + padding-left: 4px; + font-family: "Lucida Grande", "DejaVu Sans", "Bitstream Vera Sans", Verdana,Arial, sans-serif; +} +.inline-group .tabular tr td { + vertical-align: bottom; +} +.inline-group .tabular tr.has_original td.original, +.inline-group .tabular tr td.delete { + vertical-align: top; +} + +.inline-group .tabular .datetime > input { + margin-right: 5px; +} +.inline-group .tabular .datetime br { + display: none; +} diff --git a/static/modeltranslation/js/clearable_inputs.js b/static/modeltranslation/js/clearable_inputs.js new file mode 100755 index 00000000..843b159e --- /dev/null +++ b/static/modeltranslation/js/clearable_inputs.js @@ -0,0 +1,16 @@ +var jQuery, $, django; + +(function () { + 'use strict'; + (jQuery || $ || django.jQuery)(function ($) { + $('.clearable-input').each(function () { + var clear = $(this).children().last(); + $(this).find('input, select, textarea').not(clear).change(function () { + if (typeof clear.prop == "undefined") // older jQuery + clear.removeAttr('checked'); + else + clear.prop('checked', false); + }); + }); + }); +}()); diff --git a/static/modeltranslation/js/force_jquery.js b/static/modeltranslation/js/force_jquery.js new file mode 100755 index 00000000..f5de8d5f --- /dev/null +++ b/static/modeltranslation/js/force_jquery.js @@ -0,0 +1,3 @@ +if (!jQuery) { + jQuery = django.jQuery; +} diff --git a/static/modeltranslation/js/tabbed_translation_fields.js b/static/modeltranslation/js/tabbed_translation_fields.js new file mode 100755 index 00000000..a0e4266f --- /dev/null +++ b/static/modeltranslation/js/tabbed_translation_fields.js @@ -0,0 +1,423 @@ +/*jslint white: true, onevar: true, undef: true, nomen: true, eqeqeq: true, + plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true */ +var google, django, gettext; + +(function () { + var jQuery = window.jQuery || $ || django.jQuery; + + /* Add a new selector to jQuery that excludes parent items which match a given selector */ + jQuery.expr[':'].parents = function(a, i, m) { + return jQuery(a).parents(m[3]).length < 1; + }; + + jQuery(function ($) { + var TranslationField = function (options) { + this.el = options.el; + this.cls = options.cls; + this.id = ''; + this.origFieldname = ''; + this.lang = ''; + this.groupId = ''; + + this.init = function () { + var clsBits = this.cls.substring( + TranslationField.cssPrefix.length, this.cls.length).split('-'); + this.origFieldname = clsBits[0]; + this.lang = clsBits[1]; + this.id = $(this.el).attr('id'); + this.groupId = this.buildGroupId(); + }; + + this.buildGroupId = function () { + /** + * Returns a unique group identifier with respect to the admin's way + * of handling inline field name attributes. Essentially that's the + * translation field id without the language prefix. + * + * Examples ('id parameter': 'return value'): + * + * 'id_name_de': + * 'id_name' + * 'id_name_zh_tw': + * 'id_name' + * 'id_name_set-2-name_de': + * 'id_name_set-2-name' + * 'id_name_set-2-name_zh_tw': + * 'id_name_set-2-name' + * 'id_name_set-2-0-name_de': + * 'id_name_set-2-0-name' + * 'id_name_set-2-0-name_zh_tw': + * 'id_name_set-2-0-name' + * 'id_news-data2-content_type-object_id-0-name_de': + * 'id_news-data2-content_type-object_id-0-name' + * 'id_news-data2-content_type-object_id-0-name_zh_cn': + * id_news-data2-content_type-object_id-0-name' + * 'id_news-data2-content_type-object_id-0-1-name_de': + * 'id_news-data2-content_type-object_id-0-1-name' + * 'id_news-data2-content_type-object_id-0-1-name_zh_cn': + * id_news-data2-content_type-object_id-0-1-name' + */ + // TODO: We should be able to simplify this, the modeltranslation specific + // field classes are already build to be easily splitable, so we could use them + // to slice off the language code. + var idBits = this.id.split('-'), + idPrefix = 'id_' + this.origFieldname; + if (idBits.length === 3) { + // Handle standard inlines + idPrefix = idBits[0] + '-' + idBits[1] + '-' + idPrefix; + } else if (idBits.length === 4) { + // Handle standard inlines with model used by inline more than once + idPrefix = idBits[0] + '-' + idBits[1] + '-' + idBits[2] + '-' + idPrefix; + } else if (idBits.length === 5 && idBits[3] != '__prefix__') { + // Handle nested inlines (https://github.com/Soaa-/django-nested-inlines) + idPrefix = idBits[0] + '-' + idBits[1] + '-' + idBits[2] + '-' + idBits[3] + '-' + this.origFieldname; + } else if (idBits.length === 6) { + // Handle generic inlines + idPrefix = idBits[0] + '-' + idBits[1] + '-' + idBits[2] + '-' + + idBits[3] + '-' + idBits[4] + '-' + this.origFieldname; + } else if (idBits.length === 7) { + // Handle generic inlines with model used by inline more than once + idPrefix = idBits[0] + '-' + idBits[1] + '-' + idBits[2] + '-' + + idBits[3] + '-' + idBits[4] + '-' + idBits[5] + '-' + this.origFieldname; + } + return idPrefix; + }; + + this.init(); + }; + TranslationField.cssPrefix = 'mt-field-'; + + var TranslationFieldGrouper = function (options) { + this.$fields = options.$fields; + this.groupedTranslations = {}; + + this.init = function () { + // Handle fields inside collapsed groups as added by zinnia + this.$fields = this.$fields.add('fieldset.collapse-closed .mt'); + + this.groupedTranslations = this.getGroupedTranslations(); + }; + + this.getGroupedTranslations = function () { + /** + * Returns a grouped set of all model translation fields. + * The returned datastructure will look something like this: + * + * { + * 'id_name_de': { + * 'en': HTMLInputElement, + * 'de': HTMLInputElement, + * 'zh_tw': HTMLInputElement + * }, + * 'id_name_set-2-name': { + * 'en': HTMLTextAreaElement, + * 'de': HTMLTextAreaElement, + * 'zh_tw': HTMLTextAreaElement + * }, + * 'id_news-data2-content_type-object_id-0-name': { + * 'en': HTMLTextAreaElement, + * 'de': HTMLTextAreaElement, + * 'zh_tw': HTMLTextAreaElement + * } + * } + * + * The keys are unique group identifiers as returned by + * TranslationField.buildGroupId() to handle inlines properly. + */ + var self = this, + cssPrefix = TranslationField.cssPrefix; + this.$fields.each(function (idx, el) { + $.each($(el).attr('class').split(' '), function(idx, cls) { + if (cls.substring(0, cssPrefix.length) === cssPrefix) { + var tfield = new TranslationField({el: el, cls: cls}); + if (!self.groupedTranslations[tfield.groupId]) { + self.groupedTranslations[tfield.groupId] = {}; + } + self.groupedTranslations[tfield.groupId][tfield.lang] = el; + } + }); + }); + return this.groupedTranslations; + }; + + this.init(); + }; + + function createTabs(groupedTranslations) { + var tabs = []; + $.each(groupedTranslations, function (groupId, lang) { + var tabsContainer = $('
'), + tabsList = $('
    '), + insertionPoint; + tabsContainer.append(tabsList); + $.each(lang, function (lang, el) { + var container = $(el).closest('.form-row'), + label = $('label', container), + fieldLabel = container.find('label'), + tabId = 'tab_' + $(el).attr('id'), + panel, + tab; + // Remove language and brackets from field label, they are + // displayed in the tab already. + if (fieldLabel.html()) { + fieldLabel.html(fieldLabel.html().replace(/ \[.+\]/, '')); + } + if (!insertionPoint) { + insertionPoint = { + 'insert': container.prev().length ? 'after' : + container.next().length ? 'prepend' : 'append', + 'el': container.prev().length ? container.prev() : container.parent() + }; + } + container.find('script').remove(); + panel = $('
    ').append(container); + tab = $('' + lang.replace('_', '-') + ''); + tabsList.append(tab); + tabsContainer.append(panel); + }); + insertionPoint.el[insertionPoint.insert](tabsContainer); + tabsContainer.tabs(); + tabs.push(tabsContainer); + }); + return tabs; + } + + function handleAddAnotherInline() { + // TODO: Refactor + $('.mt').parents('.inline-group').not('.tabular').find('.add-row a').click(function () { + var grouper = new TranslationFieldGrouper({ + $fields: $(this).parent().prev().prev().find('.mt') + }); + var tabs = createTabs(grouper.groupedTranslations); + // Update the main switch as it is not aware of the newly created tabs + MainSwitch.update(tabs); + // Activate the language tab selected in the main switch + MainSwitch.activateTab(tabs); + }); + } + + var TabularInlineGroup = function (options) { + this.id = options.id; + this.$id = null; + this.$table = null; + this.translationColumns = []; + // TODO: Make use of this to flag required tabs + this.requiredColumns = []; + + this.init = function () { + this.$id = $('#' + this.id); + this.$table = $(this.$id).find('table'); + }; + + this.getAllGroupedTranslations = function () { + var grouper = new TranslationFieldGrouper({ + $fields: this.$table.find('.mt').filter( + 'input:visible, textarea:visible, select:visible') + }); + //this.requiredColumns = this.getRequiredColumns(); + this.initTable(); + return grouper.groupedTranslations; + }; + + this.getGroupedTranslations = function ($fields) { + var grouper = new TranslationFieldGrouper({ + $fields: $fields + }); + return grouper.groupedTranslations; + }; + + this.initTable = function () { + var self = this; + // The table header requires special treatment. In case an inline + // is declared with extra=0, the translation fields are not visible. + var thGrouper = new TranslationFieldGrouper({ + $fields: this.$table.find('.mt').filter('input, textarea, select') + }); + this.translationColumns = this.getTranslationColumns(thGrouper.groupedTranslations); + + // The markup of tabular inlines is kinda weird. There is an additional + // leading td.original per row, so we have one td more than ths. + this.$table.find('th').each(function (idx) { + // Hide table heads from which translation fields have been moved out. + if($.inArray(idx + 1, self.translationColumns) !== -1) { + // FIXME: Why does this break when we use remove instead of hide? + $(this).hide(); + } + + // Remove language and brackets from table header, + // they are displayed in the tab already. + if ($(this).html() && $.inArray(idx + 1, self.translationColumns) === -1) { + $(this).html($(this).html().replace(/ \[.+\]/, '')); + } + }); + }; + + this.getTranslationColumns = function (groupedTranslations) { + var translationColumns = []; + // Get table column indexes which have translation fields, but omit the first + // one per group, because that's where we insert our tab container. + $.each(groupedTranslations, function (groupId, lang) { + var i = 0; + $.each(lang, function (lang, el) { + var column = $(el).closest('td').prevAll().length; + if (i > 0 && $.inArray(column, translationColumns) === -1) { + translationColumns.push(column); + } + i += 1; + }); + }); + return translationColumns; + }; + + this.getRequiredColumns = function () { + var requiredColumns = []; + // Get table column indexes which have required fields, but omit the first + // one per group, because that's where we insert our tab container. + this.$table.find('th.required').each(function () { + requiredColumns.push($(this).index() + 1); + }); + return requiredColumns; + }; + + this.init(); + }; + + function handleTabularAddAnotherInline(tabularInlineGroup) { + tabularInlineGroup.$table.find('.add-row a').click(function () { + var tabs = createTabularTabs( + tabularInlineGroup.getGroupedTranslations( + $(this).parent().parent().prev().prev().find('.mt'))); + // Update the main switch as it is not aware of the newly created tabs + MainSwitch.update(tabs); + // Activate the language tab selected in the main switch + MainSwitch.activateTab(tabs); + }); + } + + function createTabularTabs(groupedTranslations) { + var tabs = []; + + $.each(groupedTranslations, function (groupId, lang) { + var tabsContainer = $(''), + tabsList = $('
      '), + insertionPoint; + tabsContainer.append(tabsList); + + $.each(lang, function (lang, el) { + var $container = $(el).closest('td'), + $panel, + $tab, + tabId = 'tab_' + $(el).attr('id'); + if (!insertionPoint) { + insertionPoint = { + 'insert': $container.prev().length ? 'after' : + $container.next().length ? 'prepend' : 'append', + 'el': $container.prev().length ? $container.prev() : $container.parent() + }; + } + $panel = $('
      ').append($container); + + // Turn the moved tds into divs + var attrs = {}; + $.each($container[0].attributes, function(idx, attr) { + attrs[attr.nodeName] = attr.nodeValue; + }); + $container.replaceWith(function () { + return $('
      ', attrs).append($(this).contents()); + }); + + // TODO: Setting the required state based on the default field is naive. + // The user might have tweaked his admin. We somehow have to keep track of the + // column indexes _before_ the tds have been moved around. + $tab = $('' + lang.replace('_', '-') + ''); + tabsList.append($tab); + tabsContainer.append($panel); + }); + insertionPoint.el[insertionPoint.insert](tabsContainer); + tabsContainer.tabs(); + tabs.push(tabsContainer); + }); + return tabs; + } + + var MainSwitch = { + languages: [], + $select: $('