изменения по закрытию 6 этапа

remotes/origin/stage6
Alexander Burdeinyi 9 years ago
parent 8510e70b73
commit 42ed23a47a
  1. 12
      comments/views.py
  2. 3
      conference/views.py
  3. 18
      emencia/django/newsletter/migrations/0016_auto__add_field_contact_from_events.py
  4. 2
      emencia/django/newsletter/models.py
  5. 13
      events/views.py
  6. 6
      static/client/css/main.css
  7. 3
      static/client/html-cut/paid_exposition.html
  8. 40
      static/client/js/_modules/page.exposition.object.js
  9. 89
      templates/client/article/article.html
  10. 9
      templates/client/includes/conference/conference_partner.html
  11. 34
      templates/client/popups/event_news_subscribe.html

@ -37,4 +37,16 @@ class CommentMixin(FormMixin):
if self.request.method == 'POST' and self.commentform.is_valid():
self.save_comment()
context['commentform'] = self.commentform
_comments = list(self.object.comments.all())
comments = {x.pk: x for x in filter(lambda x: x.parent is None, _comments)}
for comment in filter(lambda x: x.parent is not None, _comments):
try:
p = comments[comment.parent_id]
if hasattr(p, 'childs'):
p.childs.append(comment)
else:
p.childs = [comment]
except IndexError:
pass
context['comments'] = comments.values()
return context

@ -18,6 +18,7 @@ from django.utils.translation import ugettext as _
from django.views.generic import DetailView
from django.views.generic.edit import FormMixin
from comments.views import CommentMixin
from functions.cache_mixin import CacheMixin, JitterCacheMixin
from functions.custom_views import ListView, ReverseOrderMixin
from functions.views_help import get_side_items
@ -429,7 +430,7 @@ class ConferenceServiceView(FormMixin, DetailView):
return self.initial.copy()
class ConferenceDetail(ObjectStatMixin, JitterCacheMixin, MetadataMixin, DetailView):
class ConferenceDetail(ObjectStatMixin, CommentMixin, JitterCacheMixin, MetadataMixin, DetailView):
cache_range = settings.CACHE_RANGE
model = Conference
slug_field = 'url'

@ -8,8 +8,8 @@ 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',
# Adding field 'Contact.events_news'
db.add_column(u'newsletter_contact', 'events_news',
self.gf('django.db.models.fields.BooleanField')(default=False),
keep_default=False)
@ -33,8 +33,8 @@ class Migration(SchemaMigration):
def backwards(self, orm):
# Deleting field 'Contact.from_events'
db.delete_column(u'newsletter_contact', 'from_events')
# Deleting field 'Contact.events_news'
db.delete_column(u'newsletter_contact', 'events_news')
# Removing M2M table for field conferences on 'Contact'
db.delete_table(db.shorten_name(u'newsletter_contact_conferences'))
@ -256,7 +256,7 @@ class Migration(SchemaMigration):
'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)'}),
'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2016, 11, 22, 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'}),
@ -329,7 +329,7 @@ class Migration(SchemaMigration):
'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)'}),
'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2016, 11, 22, 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'}),
@ -438,7 +438,7 @@ class Migration(SchemaMigration):
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'}),
'activation_code': ('django.db.models.fields.CharField', [], {'default': "'f0ee2280ab463a4d1e0c68acfbe98b44115b34a2'", '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'}),
@ -447,11 +447,11 @@ class Migration(SchemaMigration):
'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'}),
'events_news': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'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'}),
@ -543,7 +543,7 @@ class Migration(SchemaMigration):
'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)'}),
'fr': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2016, 11, 22, 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'})

@ -151,7 +151,7 @@ class Contact(models.Model):
)
activated = models.BooleanField(default=False)
from_users = models.BooleanField(default=False)
from_events = models.BooleanField(default=False)
events_news = models.BooleanField(default=False)
moscow = models.BooleanField(_(u'Москва'), blank=True, default=True)
russia = models.BooleanField(_(u'Россия'), blank=True, default=True)

@ -8,6 +8,7 @@ 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 django.utils.translation import ugettext_lazy as _
from haystack.query import SearchQuerySet
@ -113,6 +114,7 @@ class SubscribeView(FormView):
'last_name': user.last_name,
'email': user.email,
'user': user,
'subscriber': False,
}
defaults.update(self.defaults)
try:
@ -133,12 +135,19 @@ class SubscribeView(FormView):
return HttpResponseNotFound()
return super(SubscribeView, self).dispatch(request, *args, **kwargs)
# def get_form(self, form_class):
# form = super(SubscribeView, self).get_form(form_class)
# form.fields['email'].error_messages.update({
# 'unique': _(u'Тест')
# })
# # import pdb; pdb.set_trace()
# return form
def form_invalid(self, form):
return JsonResponse(form.errors, status=400)
return JsonResponse({'errors': form.errors})
def form_valid(self, form):
contact = form.save(commit=False)
contact.send_activation()
return self.success_responce()

@ -2643,6 +2643,7 @@ a.icon-big-ical {
.editor-wrap,
input[type=text],
input[type=password],
input[type=email],
textarea {
border: 1px solid #bdbdbd;
outline: 0;
@ -2697,6 +2698,7 @@ textarea:focus {
resize: none
}
.pw-form input[type=text],
.pw-form input[type=email],
.pw-form input[type=password] {
height: 40px
}
@ -12703,6 +12705,7 @@ button.gray:hover {
margin-right: 8px;
margin-top: -8px
}
.thank-registering {
font-size: 16px
}
@ -12829,6 +12832,9 @@ button.gray:hover {
.advertise-window header {
padding-bottom: 0
}
.event-news-subscribe-modal .pw-form .pwf-field {
width: 340px
}
.expo-place-page .i-info .i-descr {
height: auto
}

@ -2469,6 +2469,9 @@
advertise:{
id:"advert-member-form"
},
event_news_subscribe:{
id: "event-news-subscribe-form"
},
addCalendarText:"В расписание",
removeCalendarText:"Из расписания"
});

@ -146,6 +146,46 @@ if (EXPO.exposition.object){
return false;
});
/**
* event news subscribe form validation
*/
$('#'+this.opt.event_news_subscribe.id).on("submit", function () {
var formData = $(this).serialize(),
formUrl = $(this).attr("action"),
$form = $(this),
/**
* executes after AJAX get request is complete
* @param data - data recieved from server ex
*/
handler = function (data) {
var clearValue = function () {
$('.err',$form).removeClass("err");
$('.pwf-msg',$form).text('');
};
if (data.success != true){
clearValue();
for (var k in data.errors){
console.log(data.errors.hasOwnProperty(k));
console.log(k);
if (data.errors.hasOwnProperty(k)) {
$('input[name="'+k+'"]',$form)
.closest(".required").addClass("err")
.siblings(".pwf-msg").text(data.errors[k]);
}
}
}else{
clearValue();
dataLayer.push({'event': 'event-news-subscribe-form'});
$('input:text',$form).val('');
$.fancybox.close();
}
$waiter.hide();
};
$waiter.show();
com.postRequest(formData,formUrl,handler);
return false;
});
};
return that;

@ -152,7 +152,7 @@
<div class="article_comments">
<h2>{% trans 'Комментарии' %}</h2>
{% for comment in object.comments.all %}
{% for comment in comments %}
<div class="comment">
<div class="comment_author">
{{ comment.user.get_full_name }} <time><i class="fa fa-calendar"></i> {{ comment.created }}</time>
@ -160,52 +160,53 @@
<div class="comment_text">{{ comment.text }}</div>
<a href="#" data-parent="{{ comment.pk }}"><i class="fa fa-comment"></i> <span>{% trans "Ответить на комментарий" %}</span></a>
<div class="comment">
<div class="comment_author">
{{ comment.user.get_full_name }} <time><i class="fa fa-calendar"></i> {{ comment.created }}</time>
{% for answer in comment.childs %}
<div class="comment">
<div class="comment_author">
{{ answer.user.get_full_name }} <time><i class="fa fa-calendar"></i> {{ answer.created }}</time>
</div>
<div class="comment_text">{{ answer.text }}</div>
</div>
<div class="comment_text">{{ comment.text }}</div>
{# <a href="#" data-parent="{{ comment.pk }}"><i class="fa fa-comment"></i> <span>{% trans "Ответить на комментарий" %}</span></a>#}
</div>
{% endfor %}
</div>
{% endfor %}
<div class="comment">
<div class="comment_author">
John Smith <time><i class="fa fa-calendar"></i> 13 апреля 2016</time>
</div>
<div class="comment_text">Сайт рыбатекст поможет дизайнеру, верстальщику, вебмастеру сгенерировать несколько абзацев более менее осмысленного текста рыбы на русском языке, а начинающему оратору отточить навык публичных выступлений в домашних условиях. При создании генератора мы использовали небезызвестный универсальный код речей. Текст генерируется абзацами случайным образом от двух до десяти предложений в абзаце, что позволяет сделать текст более привлекательным и живым для визуально-слухового восприятия.</div>
<a href="#"><i class="fa fa-comment"></i> <span>Ответить на комментарий</span></a>
</div>
<div class="comment">
<div class="comment_author">
John Smith <time><i class="fa fa-calendar"></i> 13 апреля 2016</time>
</div>
<div class="comment_text">Сайт рыбатекст поможет дизайнеру, верстальщику, вебмастеру сгенерировать несколько абзацев более менее осмысленного текста рыбы на русском языке, а начинающему оратору отточить навык публичных выступлений в домашних условиях. При создании генератора мы использовали небезызвестный универсальный код речей. Текст генерируется абзацами случайным образом от двух до десяти предложений в абзаце, что позволяет сделать текст более привлекательным и живым для визуально-слухового восприятия.</div>
<a href="#"><i class="fa fa-comment"></i> <span>Ответить на комментарий</span></a>
</div>
<div class="comment">
<div class="comment_author">
John Smith <time><i class="fa fa-calendar"></i> 13 апреля 2016</time>
</div>
<div class="comment_text">Сайт рыбатекст поможет дизайнеру, верстальщику, вебмастеру сгенерировать несколько абзацев более менее осмысленного текста рыбы на русском языке, а начинающему оратору отточить навык публичных выступлений в домашних условиях. При создании генератора мы использовали небезызвестный универсальный код речей. Текст генерируется абзацами случайным образом от двух до десяти предложений в абзаце, что позволяет сделать текст более привлекательным и живым для визуально-слухового восприятия.</div>
<a href="#"><i class="fa fa-comment"></i> <span>Ответить на комментарий</span></a>
<div class="comment">
<div class="comment_author">
John Smith <time><i class="fa fa-calendar"></i> 13 апреля 2016</time>
</div>
<div class="comment_text">Сайт рыбатекст поможет дизайнеру, верстальщику, вебмастеру сгенерировать несколько абзацев более менее осмысленного текста рыбы на русском языке, а начинающему оратору отточить навык публичных выступлений в домашних условиях. При создании генератора мы использовали небезызвестный универсальный код речей. Текст генерируется абзацами случайным образом от двух до десяти предложений в абзаце, что позволяет сделать текст более привлекательным и живым для визуально-слухового восприятия.</div>
<a href="#"><i class="fa fa-comment"></i> <span>Ответить на комментарий</span></a>
</div>
</div>
{##}
{# <div class="comment">#}
{# <div class="comment_author">#}
{# John Smith <time><i class="fa fa-calendar"></i> 13 апреля 2016</time>#}
{# </div>#}
{##}
{# <div class="comment_text">Сайт рыбатекст поможет дизайнеру, верстальщику, вебмастеру сгенерировать несколько абзацев более менее осмысленного текста рыбы на русском языке, а начинающему оратору отточить навык публичных выступлений в домашних условиях. При создании генератора мы использовали небезызвестный универсальный код речей. Текст генерируется абзацами случайным образом от двух до десяти предложений в абзаце, что позволяет сделать текст более привлекательным и живым для визуально-слухового восприятия.</div>#}
{##}
{# <a href="#"><i class="fa fa-comment"></i> <span>Ответить на комментарий</span></a>#}
{# </div>#}
{##}
{# <div class="comment">#}
{# <div class="comment_author">#}
{# John Smith <time><i class="fa fa-calendar"></i> 13 апреля 2016</time>#}
{# </div>#}
{##}
{# <div class="comment_text">Сайт рыбатекст поможет дизайнеру, верстальщику, вебмастеру сгенерировать несколько абзацев более менее осмысленного текста рыбы на русском языке, а начинающему оратору отточить навык публичных выступлений в домашних условиях. При создании генератора мы использовали небезызвестный универсальный код речей. Текст генерируется абзацами случайным образом от двух до десяти предложений в абзаце, что позволяет сделать текст более привлекательным и живым для визуально-слухового восприятия.</div>#}
{##}
{# <a href="#"><i class="fa fa-comment"></i> <span>Ответить на комментарий</span></a>#}
{# </div>#}
{##}
{# <div class="comment">#}
{# <div class="comment_author">#}
{# John Smith <time><i class="fa fa-calendar"></i> 13 апреля 2016</time>#}
{# </div>#}
{# <div class="comment_text">Сайт рыбатекст поможет дизайнеру, верстальщику, вебмастеру сгенерировать несколько абзацев более менее осмысленного текста рыбы на русском языке, а начинающему оратору отточить навык публичных выступлений в домашних условиях. При создании генератора мы использовали небезызвестный универсальный код речей. Текст генерируется абзацами случайным образом от двух до десяти предложений в абзаце, что позволяет сделать текст более привлекательным и живым для визуально-слухового восприятия.</div>#}
{# <a href="#"><i class="fa fa-comment"></i> <span>Ответить на комментарий</span></a>#}
{##}
{# <div class="comment">#}
{# <div class="comment_author">#}
{# John Smith <time><i class="fa fa-calendar"></i> 13 апреля 2016</time>#}
{# </div>#}
{##}
{# <div class="comment_text">Сайт рыбатекст поможет дизайнеру, верстальщику, вебмастеру сгенерировать несколько абзацев более менее осмысленного текста рыбы на русском языке, а начинающему оратору отточить навык публичных выступлений в домашних условиях. При создании генератора мы использовали небезызвестный универсальный код речей. Текст генерируется абзацами случайным образом от двух до десяти предложений в абзаце, что позволяет сделать текст более привлекательным и живым для визуально-слухового восприятия.</div>#}
{# <a href="#"><i class="fa fa-comment"></i> <span>Ответить на комментарий</span></a>#}
{# </div>#}
{# </div>#}
{% if user.is_authenticated %}
<div class="сomment_form">

@ -298,6 +298,7 @@
<div class="im-title">{% trans 'Спикеры' %}</div>
<p>{% trans 'Разместите информацию о ключевых спикерах' %}</p>
<p><a href="#pw-advertise" class="button icon-up pw-open" >{% trans 'Рекламировать спикера' %}</a></p>
<p><a href="#pw-event-news-subscribe" class="button icon-up pw-open" >{% trans 'Подписаться на новости' %}</a></p>
</header>
{% endif %}
{% endwith %}
@ -428,13 +429,14 @@
{% block popup %}
{% include 'client/popups/advertise_member.html' with form=advertising_form %}
{% include 'client/popups/event_news_subscribe.html' %}
{% endblock %}
{% block scripts %}
{% if request.GET.debug == '1' %}
<script src="{% static 'client/js/_modules/page.exposition.object.js' %}"></script>
<script src="{% static 'client/js/_modules/page.exposition.object.js' %}"></script>
{% else %}
<script src="{% static 'client/js_min/_modules/page.exposition.object.min.js' %}"></script>
<script src="{% static 'client/js_min/_modules/page.exposition.object.min.js' %}"></script>
{% endif %}
<script>
EXPO.exposition.object.init({
@ -455,6 +457,9 @@
advertise:{
id:"advert-member-form"
},
event_news_subscribe:{
id: "event-news-subscribe-form"
},
addCalendarText:"{% trans 'В расписание' %}",
removeCalendarText:"{% trans 'Из расписания' %}"
});

@ -0,0 +1,34 @@
{% load static %}
{% load i18n %}
<div id="pw-event-news-subscribe" class="popup-window event-news-subscribe-modal" style="display: none;">
<section>
<header class="clearfix">
<div class="pw-title">{% trans 'Подписка на новости' %} {{ object.name }}</div>
</header>
<div class="pw-body clearfix">
<form id="event-news-subscribe-form" method="post" class="pw-form" action="{% url 'events:subscribe' object.event_type object.url %}">
{% csrf_token %}
{% if not user.is_authenticated %}
<div class="pwf-line">
<div class="pwf-field required">
<input type="email" name="email" id="id_email" placeholder="Email">
</div>
<div class="pwf-msg"></div>
</div>
<div class="pwf-line">
<div class="pwf-field required">
<input type="text" name="first_name" id="id_firstname" placeholder="{% trans 'Ваше Имя' %}">
</div>
<div class="pwf-msg"></div>
</div>
{% endif %}
<div class="pwf-buttons-line">
<button type="submit" class="icon-check">{% trans 'Подписаться' %}</button>
</div>
</form>
</div>
</section>
</div>
Loading…
Cancel
Save