рефакторинг подписки на рассылку

remotes/origin/HEAD
Slava Kyrachevsky 9 years ago
parent b0474efc90
commit a74841c18a
  1. 2
      apps/accounts/urls.py
  2. 41
      apps/accounts/views.py
  3. 11
      apps/emencia/django/newsletter/forms.py
  4. 2
      apps/emencia/django/newsletter/urls/__init__.py
  5. 125
      apps/emencia/django/newsletter/views/expo_views.py
  6. 41
      static/mailing_settings/css/main.css
  7. 187
      templates/client/newsletters/mailing_settings.html

@ -8,7 +8,6 @@ from views import (
CalendarView,
Feed,
HomeView,
MailingSettings,
NameView,
PhoneView,
ProfileCompanyView,
@ -21,7 +20,6 @@ from views import (
urlpatterns = patterns('',
url(r'^profile/company/$', login_required(ProfileCompanyView.as_view())),
url(r'^profile/mailing/$', MailingSettings.as_view(), name='accounts-mailing_settings'),
url(r'^profile/settings/$', login_required(SettingsView.as_view()), name='accounts_settings'),
url(r'^profile/calendar/remove/$', 'accounts.views.remove_from_calendar'),
url(r'^profile/calendar/export/$', 'core.views.download_workbook'),

@ -27,7 +27,7 @@ from company.edit_forms import NameForm as CompNameForm, HomeForm as CompHomeFor
EmailForm as CompEmailForm, WebPageForm as CompWebPageForm, SocialForm as CompSocialForm,\
TagForm as CompTagForm, DescriptionForm as CompDescr, StaffForm as CompStaff, \
FoundationForm as CompFound, SpecializationForm as CompSpec, AddressForm as CompAddress
from emencia.django.newsletter.forms import SubscribeSettingsForm, MailingSettingsForm
from emencia.django.newsletter.forms import SubscribeSettingsForm
from emencia.django.newsletter.models import Contact, ContactSettings
from .forms import ChangePasswordForm, FeedFilterForm
@ -115,41 +115,6 @@ class GetUserMixin(object):
return instance
class MailingSettings(GetUserMixin, ContextMixin, AjaxableResponseMixin, CreateUpdateView):
form_class = MailingSettingsForm
template_name = 'client/newsletters/mailing_settings.html'
success_url = reverse_lazy('accounts-mailing_settings')
def get_success_url(self):
return self.success_url
def get_object(self):
self.extra_ctx.update({
'r_cities': City.used.russia(),
})
instance = self.get_user()
if instance is not None:
self.extra_ctx.update({
'checked_f_countries': list(instance.f_countries.values_list('pk', flat=True)),
'checked_r_cities': list(instance.r_cities.values_list('pk', flat=True)),
'checked_tg': list(instance.tags.values_list('pk', flat=True)),
'checked_th': list(instance.themes.values_list('pk', flat=True)),
'contact': instance,
})
if self.request.GET.get('unsibscribe') and instance.subscriber:
instance.unsubscribe()
self.extra_ctx.update({'unsubscribe_success': True})
elif not instance.subscriber:
self.extra_ctx.update({'unsubscribed': True})
return instance
def form_valid(self, form):
return super(MailingSettings, self).form_valid(form)
def form_invalid(self, form):
return super(MailingSettings, self).form_invalid(form)
class CalendarView(TemplateView):
"""
display template with user calendar(one month)
@ -607,4 +572,6 @@ class UserSubscribeThemesTagsView(GetUserMixin, TemplateView):
def render_to_response(self, context, **response_kwargs):
context.pop('view')
return HttpResponse(json.dumps(context), content_type=self.content_type)
return HttpResponse(
json.dumps(context), content_type=self.content_type
)

@ -100,11 +100,13 @@ class MailingSettingsForm(forms.ModelForm):
class Meta:
model = Contact
fields = [
'moscow', 'russia', 'r_cities', 'foreign',
'email', 'first_name', 'moscow', 'russia', 'r_cities', 'foreign',
'periodic', 'periodic_day', 'content_news', 'content_overview',
'content_articles',
]
widgets = {
'email': forms.TextInput(attrs={'placeholder': _(u'Ваш e-mail')}),
'first_name': forms.TextInput(attrs={'placeholder': _(u'Ваше имя')}),
'moscow': forms.CheckboxInput(),
'foreign': forms.CheckboxInput(),
'periodic': forms.RadioSelect(),
@ -221,9 +223,10 @@ class ContactForm(forms.ModelForm):
def clean_email(self):
email = self.cleaned_data['email']
try:
self.instance = Contact.objects.get(email__iexact=email)
return email
except (Contact.DoesNotExist, ):
Contact.objects.get(email__iexact=email)
raise forms.ValidationError(_(u'Указанный e-mail адрес уже '
u'подписан на рассылку'))
except Contact.DoesNotExist:
pass
return email

@ -12,7 +12,7 @@ urlpatterns = patterns('',
url(r'^statistics/', include('emencia.django.newsletter.urls.statistics')),
url(r'^', include('emencia.django.newsletter.urls.newsletter')),
url(r'^test-letter/', TemplateView.as_view(template_name='client/newsletters/announce_template.html')),
url(r'^test-letter/', TemplateView.as_view(template_name='client/newsletters/announce_template.html'), name='newsletter_test_letter'),
url(r'^activation/send/', TemplateView.as_view(template_name='client/newsletters/activation_send.html'),
name='subscription_activation_send'),
url(r'^activation/complete/', TemplateView.as_view(template_name='client/newsletters/activation_complete.html'),

@ -3,7 +3,7 @@ import json
from django.core.urlresolvers import reverse_lazy
from django.views.generic import TemplateView, FormView
from django.http import HttpResponseRedirect, HttpResponse
from django.http import HttpResponse
from django.shortcuts import redirect
from emencia.django.newsletter.forms import ContactForm
@ -13,82 +13,89 @@ from emencia.django.newsletter.forms import (
)
from accounts.models import User
from accounts.views import GetUserMixin
from functions.custom_views import ContextMixin
from functions.http import JsonResponse
from city.models import City
class SubscribeView(GetUserMixin, ContextMixin, FormView):
form_class = ContactForm
class SubscribeView(GetUserMixin, FormView):
"""
Представление для подписки не/авторизованных пользователей
"""
template_name = 'client/newsletters/mailing_settings.html'
success_url = reverse_lazy('subscription_activation_send')
def get_form(self, form_class):
if self.request.POST:
email = self.request.POST.get('email')
if email:
try:
contact = Contact.objects.get(email=email)
return form_class(instance=contact,
**self.get_form_kwargs())
except Contact.DoesNotExist:
pass
return form_class(**self.get_form_kwargs())
else:
return form_class(**self.get_form_kwargs())
form_class = MailingSettingsForm
def get_object(self):
return self.get_user()
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super(SubscribeView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super(SubscribeView, self).post(request, *args, **kwargs)
def form_valid(self, form):
contact = form.save()
contact.send_activation()
return HttpResponseRedirect(self.success_url)
if not self.request.user.is_authenticated():
contact.send_activation()
if self.request.is_ajax():
data = {'success': True}
return JsonResponse(data)
return redirect(self.get_success_url())
def form_invalid(self, form):
if self.request.is_ajax():
data = {
'form_errors': form.errors,
'form_non_fields_errors': form.non_field_errors(),
}
return JsonResponse(data, status=400)
return self.render_to_response(self.get_context_data(form=form))
def get_initial(self):
data = super(SubscribeView, self).get_initial()
if self.request.user.is_authenticated():
email = getattr(self.request.user, 'email')
data['email'] = email
data['first_name'] = getattr(self.request.user, 'first_name')
if self.request.GET:
if self.request.GET.get('email'):
data['email'] = self.request.GET['email']
if self.request.GET.get('first_name'):
data['first_name'] = self.request.GET['first_name']
if self.request.GET.get('email'):
data['email'] = self.request.GET['email']
if self.request.GET.get('first_name'):
data['first_name'] = self.request.GET['first_name']
return data
def get_success_url(self):
if not self.request.user.is_authenticated():
return reverse_lazy('subscription_activation_send')
return reverse_lazy('newsletter_subscription')
def get_context_data(self, **kwargs):
ctx = super(SubscribeView, self).get_context_data(**kwargs)
ctx['object'] = self.get_mailsettings_object()
ctx['mailsettings_form'] = MailingSettingsForm(
instance=self.get_user()
)
ctx['object'] = self.object
ctx['r_cities'] = self.get_russian_cities()
ctx['checked_th'] = self.get_checked_th()
if self.object is not None:
if self.request.GET.get('unsibscribe') and self.object.subscriber:
self.object.unsubscribe()
ctx['unsubscribe_success'] = True
elif not self.object.subscriber:
ctx['unsubscribed'] = True
return ctx
def get_mailsettings_object(self):
def get_russian_cities(self):
"""
:return: города России
"""
return City.used.russia()
def get_checked_th(self):
"""
передаём контекст в шаблон по городам, странам, а так же выбранным
:return: instance of mail settings
:return: выбранные пользователем темы
"""
self.extra_ctx.update({
'r_cities': City.used.russia(),
})
instance = self.get_user()
if instance is not None:
self.extra_ctx.update({
'checked_f_countries': list(
instance.f_countries.values_list('pk', flat=True)),
'checked_r_cities': list(
instance.r_cities.values_list('pk', flat=True)),
'checked_tg': list(instance.tags.values_list('pk', flat=True)),
'checked_th': list(
instance.themes.values_list('pk', flat=True)),
'contact': instance,
})
if self.request.GET.get('unsibscribe') and instance.subscriber:
instance.unsubscribe()
self.extra_ctx.update({'unsubscribe_success': True})
elif not instance.subscriber:
self.extra_ctx.update({'unsubscribed': True})
return instance
if self.object is not None:
return self.object.themes.values_list('pk', flat=True)
return []
class ActivationView(TemplateView):

@ -848,7 +848,7 @@ a.themes_trigger{
.pr-input{
float:left;
height:46px;
width:186px;
width:247px;
padding:0 44px 0 18px;
margin:0 0 0 13px;
background:#fff;
@ -873,6 +873,43 @@ a.themes_trigger{
background:url(../images/pr-icon03.png) no-repeat 50% 50%;
}
.pr-form input{
padding:0;
border:none;
color:#000;
font:17px/21px 'pf_dindisplay_promedium', Arial, Helvetica, sans-serif;
height:24px;
margin:12px 0 0;
}
.pr-form input:focus::-webkit-input-placeholder {
color:transparent;
}
.pr-form input:focus:-moz-placeholder {
color:transparent;
}
.pr-form input:focus:-ms-input-placeholder {
color:transparent;
}
.pr-form input:focus::-moz-placeholder {
color:transparent;
}
.pr-form input::-webkit-input-placeholder { /* WebKit browsers */
color:#808080;
opacity:1;
}
.pr-form input:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
color:#808080;
opacity:1;
}
.pr-form input::-moz-placeholder { /* Mozilla Firefox 19+ */
color:#808080;
opacity:1;
}
.pr-form input:-ms-input-placeholder { /* Internet Explorer 10+ */
color:#808080;
opacity:1;
}
.pr-form button{
display:block;
border:2px solid #fff;
@ -890,4 +927,4 @@ a.themes_trigger{
-ms-transition: all 100ms linear;
-o-transition: all 100ms linear;
transition: all 100ms linear;
}
}

@ -10,7 +10,6 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/malihu-custom-scrollbar-plugin/3.1.5/jquery.mCustomScrollbar.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
<link rel="stylesheet" href="{% static 'mailing_settings/css/main.css' %}">
<link rel="stylesheet" href="{% static 'mailing_settings/css/form.css' %}">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js" defer></script>
</head>
@ -20,16 +19,16 @@
<header class="page_header">
<div class="container">
<div class="logo_block">
<a href="/"><img src="{% static 'mailing_settings/images/logo.png' %}" alt="Expomap"></a>
<a href="/" class="back_to_site">expomap.ru <span>&#8250;</span></a>
<a href="{% url 'index' %}"><img src="{% static 'mailing_settings/images/logo.png' %}" alt="Expomap"></a>
<a href="{% url 'index' %}" class="back_to_site">expomap.ru <span>&#8250;</span></a>
</div>
<h1>{% trans 'Настройте рассылку от Expomap' %}</h1>
<p>{% trans 'для' %} <span>{{ contact.email }}</span></p>
<p>{% trans 'для' %} <span>{{ object.email }}</span></p>
</div>
</header>
{% else %}
<header id="pr-header">
<div class="pr-center">
<div class="container">
<div class="pr-header-box">
<a class="pr-phone" href="tel:+7 (499) 999-12-07">+7 (499) 999-12-07</a>
<ul class="pr-social">
@ -41,13 +40,187 @@
<li><a href="https://twitter.com/expomap_ru"><img src="{% static 'mailing_settings/images/sm-icon-twit.png' %}" /></a></li>
</ul>
</div>
<strong class="pr-logo"><a href="/">Expomap</a></strong>
<strong class="pr-logo"><a href="{% url 'index' %}">Expomap</a></strong>
<span class="pr-slogan">{% blocktrans %}П<span class="pr-search-icon"></span>исковик деловых событий{% endblocktrans %}</span>
</div>
</header>
{% endif %}
<p>Страница в разработке</p>
<form action="." method="post" id="mailing_settings_form">
{% csrf_token %}
{% if not user.is_authenticated %}
<section id="pr-promo">
<div class="container">
<h1>{% trans 'Анонсы выставок' %} <br />{% trans 'и конференций на ваш e-mail' %}</h1>
<h2>{% trans 'Хотите быть в курсе событий?' %}</h2>
<div class="pr-promo-text">
<p>{% trans 'Получайте анонсы выставок и конференций на email каждую среду. Вы можете выбрать несколько интересующих вас тематических направлений.' %} <a target="_blank" href="{% url 'newsletter_test_letter' %}">{% trans 'Пример письма' %}</a></p>
</div>
<div class="pr-form">
<fieldset>
<div class="pr-row">
<span class="pr-input pr-name">{{ form.first_name }}</span>
<span class="pr-input pr-email" >{{ form.email }}</span>
</div>
<button>{% trans 'Подписаться' %}</button>
</fieldset>
</div>
</div>
</section>
{% endif %}
<div class="themes_block">
<div class="container">
<h2>{% trans 'Какие события включать в ваше письмо?' %}</h2>
<div class="columns">
<div class="column">
<h3>{% trans 'Ваши темы:' %}</h3>
<ul id="selected_themes" class="selected selected_themes">
{% for theme in object.themes.all %}
<li data-id="{{ theme.pk }}" data-type="th" class="theme_{{ theme.pk }}">
<input type="hidden" name="th" value="{{ theme.pk }}">
{{ theme }}
<a href="#">&times;</a>
</li>
{% endfor %}
{% for tag in object.tags.all %}
<li data-id="{{ tag.pk }}" data-type="tg" data-parent="{{ tag.theme.pk }}" class="tag_{{ tag.pk }}">
<input type="hidden" name="tg" value="{{ tag.pk }}">
{{ tag }}
<a href="#">&times;</a>
</li>
{% endfor %}
</ul>
<a href="#search-modal" class="modal_trigger themes_trigger">{% trans 'Уточнить темы' %}</a>
</div>
<div class="column">
<h3>{% trans 'Ваши гео-фильтры:' %}</h3>
<ul class="geo_filters">
<li>
<label>
{{ form.moscow }}
<span class="label moscow">
<i class="fa fa-map-marker"></i>
{{ form.moscow.label }}
</span>
<span class="geo_checkbox"></span>
</label>
</li>
<li>
<label>
{{ form.russia }}
<span class="label rf">
<i class="fa fa-map-marker"></i>
{{ form.russia.label }}
</span>
<span class="geo_checkbox"></span>
</label>
<a href="#cities-modal" class="modal_trigger">{% trans 'Выбрать города' %}</a>
<ul id="selected_cities" class="selected"></ul>
{{ form.r_cities }}
</li>
<li>
<label>
{{ form.foreign }}
<span class="label foreign">
<i class="fa fa-map-marker"></i>
{{ form.foreign.label }}
</span>
<span class="geo_checkbox"></span>
</label>
<a href="#countries_modal" class="modal_trigger">{% trans 'Выбрать страны' %}</a>
<ul id="selected_areas" class="selected"></ul>
<ul id="selected_countries" class="selected"></ul>
{{ form.area }}
{{ form.co }}
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="subjects_block">
<div class="container">
<h2>{% trans 'Включать ли новости / обзоры / статьи в письмо?' %}</h2>
<div class="columns">
<div class="column">
{{ form.content_news }}
{{ form.content_news.label_tag }}
<p>{% trans "Получайте новости выставок и конференций по выбранным тематикам" %}</p>
</div>
<div class="column">
{{ form.content_overview }}
{{ form.content_overview.label_tag }}
<p>{% trans "Практические материалы, интервью, кейсы, которые помогут эффективно участвовать в выставках" %}</p>
</div>
<div class="column">
{{ form.content_articles }}
{{ form.content_articles.label_tag }}
<p>{% trans "Блог о том, как создавать и продвигать крутые event`ы" %}</p>
</div>
</div>
</div>
</div>
<div class="period_block">
<div class="container">
<h2>{% trans 'Регулярность получения писем' %}</h2>
<div class="columns">
<div class="column periodic">
<ul>
{% for field in form.periodic %}
<li>
<label>
{{ field.tag }}
<span class="radio">
{{ field.choice_label }}
</span>
</label>
</li>
{% endfor %}
</ul>
</div>
<div class="column mailing_day">
{% for field in form.periodic_day %}
<label>
{{ field.tag }}
<span class="radio">
{{ field.choice_label }}
</span>
</label>
{% endfor %}
</div>
</div>
</div>
</div>
<div class="button_block">
<div class="container">
<div class="tos">
<strong>{% trans 'Нажимая «Подписаться», вы соглашаетесь получать' %} <br /> {% trans 'материалы компании Expomap на свой электронный адрес' %} </strong>
<a href="{% url 'termsofuse' %}" style="color:#a2a2a2;">{% trans "Пользовательское соглашение" %}</a>
</div>
<button type="submit">{% trans "Сохранить" %}</button>
<a href="?unsibscribe=1">{% trans 'Не хочу быть в курсе событий (отписаться от всего)' %}</a>
</div>
</div>
</form>
<footer class="page_footer">&copy; Expomap {% now "Y" %}</footer>
<div class="modals">
<div id="search-modal">
{% include 'client/popups/new_themes.html' %}
</div>
<div id="cities-modal">
{% include 'client/popups/russia_cities.html' %}
</div>
<div id="countries_modal">
{% include 'client/popups/mailing_settings_countries.html' %}
</div>
{% if unsubscribe_success or unsubscribed %}
<div id="unsibscribed_modal">
{% include 'client/popups/unsubscribed.html' %}
</div>
{% endif %}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.4/jquery.fancybox.pack.min.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/malihu-custom-scrollbar-plugin/3.1.5/jquery.mCustomScrollbar.min.js" defer></script>

Loading…
Cancel
Save