Merge branch 'newsletter' of git.general-servers.com:expomap/expomap into newsletter

remotes/origin/1203
Nazar Kotjuk 10 years ago
commit 9963687752
  1. 1
      article/forms.py
  2. 6
      emencia/django/newsletter/admin_forms.py
  3. 4
      emencia/django/newsletter/admin_urls.py
  4. 40
      emencia/django/newsletter/forms.py
  5. 2
      emencia/django/newsletter/models.py
  6. 6
      emencia/django/newsletter/utils/excel.py
  7. 46
      emencia/django/newsletter/views/admin_views.py
  8. 23
      static/js/select/select2.min.js
  9. 11
      templates/admin/newsletters/confirm_delete.html
  10. 1
      templates/admin/newsletters/contact.html
  11. 158
      templates/admin/newsletters/contact_list.html

@ -131,6 +131,7 @@ class NewsForm(BlogForm):
except Conference.DoesNotExist: except Conference.DoesNotExist:
return None return None
class ArticleForm(forms.Form): class ArticleForm(forms.Form):
""" """
Create Article form for creating conference Create Article form for creating conference

@ -4,6 +4,7 @@ from django.utils.translation import ugettext_lazy as _
from ckeditor.widgets import CKEditorWidget from ckeditor.widgets import CKEditorWidget
from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, Newsletter, Attachment from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, Newsletter, Attachment
from city.models import City from city.models import City
from country.models import Country, Area
class ContactSettingsForm(forms.ModelForm): class ContactSettingsForm(forms.ModelForm):
@ -14,6 +15,8 @@ class ContactSettingsForm(forms.ModelForm):
subscriber = forms.BooleanField(label=_('subscriber'), required=False) subscriber = forms.BooleanField(label=_('subscriber'), required=False)
valid = forms.BooleanField(label=_('valid email'), required=False) valid = forms.BooleanField(label=_('valid email'), required=False)
tester = forms.BooleanField(label=_('contact tester'), required=False) tester = forms.BooleanField(label=_('contact tester'), required=False)
country = forms.MultipleChoiceField(choices=[(c.id,c.name) for c in list(set(Country.objects.language().all()))], required=False)
area = forms.MultipleChoiceField(choices=[(a.id, a.name) for a in list(set(Area.objects.language().all()))], required=False)
class Meta: class Meta:
model = ContactSettings model = ContactSettings
@ -38,15 +41,18 @@ class ContactSettingsForm(forms.ModelForm):
def clean_city(self): def clean_city(self):
return City.objects.none() return City.objects.none()
class MailingListForm(forms.ModelForm): class MailingListForm(forms.ModelForm):
class Meta: class Meta:
model = MailingList model = MailingList
fields = ('name', 'description') fields = ('name', 'description')
class NewsletterForm(forms.ModelForm): class NewsletterForm(forms.ModelForm):
test_contacts = forms.ModelMultipleChoiceField(label=u'Тестовые контакты', required=False, test_contacts = forms.ModelMultipleChoiceField(label=u'Тестовые контакты', required=False,
queryset=Contact.objects.filter(tester=True)) queryset=Contact.objects.filter(tester=True))
content = forms.CharField(label=_('content'), widget=CKEditorWidget(config_name='newsletters')) content = forms.CharField(label=_('content'), widget=CKEditorWidget(config_name='newsletters'))
class Meta: class Meta:
model = Newsletter model = Newsletter
fields = ('title', 'content', 'mailing_list', 'test_contacts', 'header_sender', fields = ('title', 'content', 'mailing_list', 'test_contacts', 'header_sender',

@ -3,7 +3,7 @@ from django.conf.urls import include
from django.conf.urls import patterns from django.conf.urls import patterns
from django.http import HttpResponse from django.http import HttpResponse
from emencia.django.newsletter.views.admin_views import ContactList, UpdateContact, MailingListView, UpdateMailingList,\ from emencia.django.newsletter.views.admin_views import ContactList, UpdateContact, MailingListView, UpdateMailingList,\
CreateMailingList, NewsletterCreate, NewsletterListView, NewsletterUpdate CreateMailingList, NewsletterListView, NewsletterCreate, ExportContacts, DeleteContact, NewsletterUpdate
urlpatterns = patterns('', urlpatterns = patterns('',
@ -16,5 +16,7 @@ urlpatterns = patterns('',
url(r'^mailinglist/', CreateMailingList.as_view(), name='newsletters_mailinglist_create'), url(r'^mailinglist/', CreateMailingList.as_view(), name='newsletters_mailinglist_create'),
url(r'^contact/(?P<pk>\d+)/edit/', UpdateContact.as_view(), name='newsletters_contact_update'), url(r'^contact/(?P<pk>\d+)/edit/', UpdateContact.as_view(), name='newsletters_contact_update'),
url(r'^contact/(?P<pk>\d+)/delete/', DeleteContact.as_view(), name='newsletters_contact_delete'),
url(r'^contact/all/$', ContactList.as_view(), name='newsletters_contact_list'), url(r'^contact/all/$', ContactList.as_view(), name='newsletters_contact_list'),
url(r'^contact/export/$', ExportContacts.as_view(), name='export_contacts'),
) )

@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
from emencia.django.newsletter.models import Contact, ContactSettings from emencia.django.newsletter.models import Contact, ContactSettings
from emencia.django.newsletter.models import MailingList from emencia.django.newsletter.models import MailingList
from functions.form_check import translit_with_separator as tr
from theme.models import Theme from theme.models import Theme
from country.models import Country, Area from country.models import Country, Area
@ -80,8 +81,39 @@ class ContactSettingsForm(forms.ModelForm):
else: else:
return Theme.objects.none() return Theme.objects.none()
class ContactFilterForm(forms.Form): class ContactFilterForm(forms.Form):
email = forms.EmailField(label=_("Email"), max_length=255) email = forms.EmailField(label="Email", max_length=255, required=False,
theme = forms.ChoiceField(label=_("Тематика"), choices = [(t.id, t.name) for t in Theme.objects.language()]) widget=forms.TextInput(attrs={'class':'input-xlarge search-query','placeholder':'Email'}))
country = forms.ChoiceField(label=_("Страна"), choices = [(c.id, c.name) for c in Country.objects.language().distinct()]) theme = forms.MultipleChoiceField(label="Тематика", choices = [(t.id, t.name) for t in Theme.objects.language()],
area = forms.ChoiceField(label=_("Страна"), choices = [(c.id, c.name) for c in Country.objects.language().distinct()]) required=False)
country = forms.MultipleChoiceField(label="Страна",
choices = [(c.id, c.name) for c in list(set(Country.objects.language('ru').all()))],
required=False)
area = forms.MultipleChoiceField(label="Area", choices = [(c.id, c.name) for c in list(set(Area.objects.language()))],
required=False)
active = forms.BooleanField(label="Подтверждена подписка", required=False)
valid = forms.BooleanField(label="Валидный Email", required=False)
def filter(self):
title = 'contact list '
qs = Contact.objects.all()
if self.cleaned_data.get('email'):
qs = qs.filter(email__icontains=self.cleaned_data['email'])
if self.cleaned_data.get('theme'):
qs = qs.filter(contactsettings__theme__id__in=self.cleaned_data['theme'])
title += " themes: %s" % ','.join([obj.url for obj in Theme.objects.language().filter(id__in=self.cleaned_data['theme'])])
if self.cleaned_data.get('country'):
qs = qs.filter(contactsettings__country__id__in=self.cleaned_data['country'])
title += " countries: %s" % ','.join([obj.url for obj in Country.objects.language().filter(id__in=self.cleaned_data['country'])])
if self.cleaned_data.get('area'):
qs = qs.filter(contactsettings__area__id__in=self.cleaned_data['area'])
title += " geo area: %s" % ','.join([obj.url for obj in Area.objects.language('en').filter(id__in=self.cleaned_data['area'])])
if self.cleaned_data.get('active'):
title = ' active ' + title
qs = qs.filter(activated=True)
if self.cleaned_data.get('valid'):
title = 'valid e-mail ' + title
qs = qs.filter(valid=True)
return qs, title

@ -198,7 +198,7 @@ class Contact(models.Model):
class ContactSettings(models.Model): class ContactSettings(models.Model):
WEEK = 1 # every week WEEK = 1 # every week
WEEK_2 = 2 # every 2 weeks WEEK_2 = 2 # every 2 weeks
MONTH = 3 # every 4 month MONTH = 3 # every 4 weeks
PERIODIC_CHOICES = [(WEEK, 'Раз в неделю'), PERIODIC_CHOICES = [(WEEK, 'Раз в неделю'),
(WEEK_2, 'Раз в 2 недели'), (WEEK_2, 'Раз в 2 недели'),

@ -10,7 +10,7 @@ from django.db.models.query import ValuesQuerySet
class ExcelResponse(HttpResponse): class ExcelResponse(HttpResponse):
"""ExcelResponse feeded by queryset""" """ExcelResponse feeded by queryset"""
def __init__(self, data, output_name='excel_data', headers=None, def __init__(self, data, output_name='excel_data', headers=None, sheet_name = "Sheet1", default_style=None,
force_csv=False, encoding='utf8'): force_csv=False, encoding='utf8'):
valid_data = False valid_data = False
if isinstance(data, ValuesQuerySet): if isinstance(data, ValuesQuerySet):
@ -40,11 +40,11 @@ class ExcelResponse(HttpResponse):
use_xls = True use_xls = True
if use_xls: if use_xls:
book = xlwt.Workbook(encoding=encoding) book = xlwt.Workbook(encoding=encoding)
sheet = book.add_sheet('Sheet 1') sheet = book.add_sheet(sheet_name)
styles = {'datetime': xlwt.easyxf(num_format_str='yyyy-mm-dd hh:mm:ss'), styles = {'datetime': xlwt.easyxf(num_format_str='yyyy-mm-dd hh:mm:ss'),
'date': xlwt.easyxf(num_format_str='yyyy-mm-dd'), 'date': xlwt.easyxf(num_format_str='yyyy-mm-dd'),
'time': xlwt.easyxf(num_format_str='hh:mm:ss'), 'time': xlwt.easyxf(num_format_str='hh:mm:ss'),
'default': xlwt.Style.default_style} 'default': default_style or xlwt.Style.default_style}
for rowx, row in enumerate(data): for rowx, row in enumerate(data):
for colx, value in enumerate(row): for colx, value in enumerate(row):
if isinstance(value, datetime.datetime): if isinstance(value, datetime.datetime):

@ -1,13 +1,14 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.views.generic import TemplateView, CreateView, ListView, UpdateView, DetailView, FormView from django.views.generic import TemplateView, CreateView, ListView, UpdateView, DeleteView, FormView
from django.views.generic.list import MultipleObjectMixin
from django.conf import settings from django.conf import settings
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.forms.formsets import BaseFormSet, formset_factory from django.forms.formsets import BaseFormSet, formset_factory
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, Newsletter, Attachment from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, Newsletter, Attachment
from emencia.django.newsletter.admin_forms import ContactSettingsForm, MailingListForm, NewsletterForm, AttachmentForm from emencia.django.newsletter.admin_forms import ContactSettingsForm, MailingListForm, NewsletterForm, AttachmentForm
from django.core.urlresolvers import reverse_lazy
from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, Newsletter from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, Newsletter
from emencia.django.newsletter.admin_forms import ContactSettingsForm, MailingListForm, NewsletterForm from emencia.django.newsletter.admin_forms import ContactSettingsForm, MailingListForm, NewsletterForm
from ..forms import ContactFilterForm from ..forms import ContactFilterForm
@ -41,12 +42,7 @@ class ContactList(FormView):
return super(ContactList, self).get(request, *args, **kwargs) return super(ContactList, self).get(request, *args, **kwargs)
def form_valid(self, form): def form_valid(self, form):
""" qs, _ = form.filter()
filtering queryset and return paginated results
"""
qs = form.filter()
result = paginate_results(qs, page=self.request.GET.get('page')) result = paginate_results(qs, page=self.request.GET.get('page'))
context = self.get_context_data(form=form) context = self.get_context_data(form=form)
context.update({'object_list': result}) context.update({'object_list': result})
@ -60,10 +56,10 @@ class ContactList(FormView):
return context return context
class DeleteContact(DeleteView):
model = ContactSettings
success_url = reverse_lazy('newsletters_contact_list')
template_name = 'admin/newsletters/confirm_delete.html'
class UpdateContact(UpdateView): class UpdateContact(UpdateView):
model = ContactSettings model = ContactSettings
@ -71,6 +67,14 @@ class UpdateContact(UpdateView):
template_name = 'admin/newsletters/contact.html' template_name = 'admin/newsletters/contact.html'
success_url = '/admin/newsletters/contact/all/' success_url = '/admin/newsletters/contact/all/'
def form_valid(self, form):
self.object = form.save()
self.object.theme = form.cleaned_data['theme']
self.object.country = form.cleaned_data['country']
self.object.area = form.cleaned_data['area']
self.object.save()
return HttpResponseRedirect(self.get_success_url())
def get_initial(self): def get_initial(self):
obj = self.object.contact obj = self.object.contact
data = self.initial.copy() data = self.initial.copy()
@ -175,4 +179,20 @@ class NewsletterUpdate(UpdateView):
class NewsletterListView(ListView): class NewsletterListView(ListView):
paginate_by = settings.ADMIN_PAGINATION paginate_by = settings.ADMIN_PAGINATION
model = Newsletter model = Newsletter
template_name = 'admin/newsletters/newsletter_list.html' template_name = 'admin/newsletters/newsletter_list.html' success_url = '/admin/newsletters/newsletters/all/'
from ..utils.excel import ExcelResponse
class ExportContacts(FormView):
form_class = ContactFilterForm
def get(self, request=None, *args, **kwargs):
form = self.form_class(request.GET)
if form.is_valid():
qs, title = form.filter()
if qs.count():
columns = ('first_name', 'email')
return ExcelResponse(qs, title, columns,'contacts')
return HttpResponseRedirect(self.request.META['HTTP_REFERER'])

File diff suppressed because one or more lines are too long

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% block sidebar %}{% endblock %}
{% block body %}
<form action="" method="post">{% csrf_token %}
<div class="controls">
<p>Вы точно хотите удалить "{{ object.contact.name }}" ?</p>
<input class="btn btn-large btn-danger delete" type="submit" value="Да" />
<a class="btn btn-large btn-primary" href = {% url 'newsletters_contact_list' %}>Нет</a>
</div>
</form>
{% endblock %}

@ -10,6 +10,7 @@
$('#id_theme').select2({width: "element"}); $('#id_theme').select2({width: "element"});
$('#id_country').select2({width: "element"}); $('#id_country').select2({width: "element"});
$('#id_area').select2({width:'element'});
}) })
</script> </script>

@ -1,5 +1,5 @@
{% extends 'admin/base.html' %} {% extends 'admin/base.html' %}
{% load staticfiles %}
{% block body %} {% block body %}
<div class="box span10"> <div class="box span10">
@ -9,65 +9,75 @@
<div class="box-content"> <div class="box-content">
<form class="form-horizontal" method="get"> <form class="form-horizontal" method="get">
<fieldset> <fieldset>
<!-- Form Name --> <!-- Form Name -->
<legend>Filter subscribers</legend> <legend>Filter subscribers <i class="icon-circle-arrow-down"></i></legend>
<div class="toggled">
<!-- Search input-->
<div class="control-group"> <!-- Email -->
<label class="control-label" for="id_email">{{ form.email.label }}</label> <div class="control-group">
<label class="control-label" for="id_email">{{ form.email.label }}</label>
<div class="controls"> <div class="controls">
{# <input id="Email" name="Email" type="text" placeholder="Email"#} {{ form.email }}
{# class="input-xlarge search-query">#} </div>
{{ form.email }}
</div> </div>
</div>
<!-- Select Basic -->
<div class="control-group">
<label class="control-label" for="id_theme">{{ form.theme.label }}</label>
<div class="controls"> <!-- Theme -->
{{ form.theme }} <div class="control-group">
<label class="control-label" for="id_theme">{{ form.theme.label }}</label>
<div class="controls">
{{ form.theme }}
</div>
</div> </div>
</div>
<!-- Select Basic --> <!-- Country -->
<div class="control-group"> <div class="control-group">
<label class="control-label" for="id_country">{{ form.id_country }}</label> <label class="control-label" for="id_country">{{ form.country.label }}</label>
<div class="controls">
{{ form.country }}
</div>
</div>
<div class="controls"> <!-- Area -->
{{ form.country }} <div class="control-group">
<label class="control-label" for="id_area">{{ form.area.label }}</label>
<div class="controls">
{{ form.area }}
</div>
</div> </div>
</div>
<!-- Select Basic --> <!-- Submit newsletter -->
<div class="control-group"> <div class="control-group">
<label class="control-label" for="id_area">{{ form.area.label }}</label> <label class="control-label" for="id_active">{{ form.active.label }}</label>
<div class="controls">
{{ form.active }}
</div>
</div>
<div class="controls"> <!-- Valid email -->
{{ form.area }} <div class="control-group">
<label class="control-label" for="id_area">{{ form.valid.label }}</label>
<div class="controls">
{{ form.valid }}
</div>
</div> </div>
</div>
<!-- Button --> <!-- Buttons -->
<div class="control-group"> <div class="control-group">
<label class="control-label" for="submit"></label> <label class="control-label" for="submit"></label>
<div class="controls"> <div class="controls">
<button id="submit" name="submit" class="btn btn-info">Filter</button> <button id="submit" class="btn btn-primary">Filter</button>
<a href="{% url 'export_contacts' %}" id="export" class="btn btn-warning">Export to xls <i class="icon-circle-arrow-down"></i></a>
</div>
</div> </div>
</div> </div>
</fieldset> </fieldset>
</form> </form>
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<tr> <tr>
<th>Email</th> <th>Email</th>
<th>Имя</th> <th>Имя</th>
@ -78,27 +88,55 @@
<th>Дата редактирования</th> <th>Дата редактирования</th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for item in object_list %} {% for item in object_list %}
<tr> <tr>
<td>{{ item.email }}</td> <td>{{ item.email }}</td>
<td>{{ item.first_name }}</td> <td>{{ item.first_name }}</td>
<td>{% if item.tester %}<span class="label label-success">да</span>{% else %}<span class="label label-important">нет</span>{% endif %}</td> <td>{% if item.tester %}<span class="label label-success">да</span>{% else %}
<td>{% if item.subscriber %}<span class="label label-success">да</span>{% else %}<span class="label label-important">нет</span>{% endif %}</td> <span class="label label-important">нет</span>{% endif %}</td>
<td>{% if item.activated %}<span class="label label-success">да</span>{% else %}<span class="label label-important">нет</span>{% endif %}</td> <td>{% if item.subscriber %}<span class="label label-success">да</span>{% else %}
<td>{{ item.creation_date|date:"Y-m-d H:i" }}</td> <span class="label label-important">нет</span>{% endif %}</td>
<td>{{ item.modification_date|date:"Y-m-d H:i" }}</td> <td>{% if item.activated %}<span class="label label-success">да</span>{% else %}
<span class="label label-important">нет</span>{% endif %}</td>
<td><a href="{% url 'newsletters_contact_update' item.contactsettings.id %}">Изменить</a> </td> <td>{{ item.creation_date|date:"Y-m-d H:i" }}</td>
</tr> <td>{{ item.modification_date|date:"Y-m-d H:i" }}</td>
{% endfor %}
</tbody> <td><a href="{% url 'newsletters_contact_update' item.contactsettings.id %}">Изменить</a></td>
</table> </tr>
{% endfor %}
</tbody>
</table>
</div>
{# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}
</div> </div>
{# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}
</div>
{% endblock %} {% endblock %}
{% block scripts %}
<script src="{% static 'js/select2.min.js' %}"></script>
<link href="{% static 'js/select/select2.css' %}" rel='stylesheet'>
<script>
$(document).ready(function () {
$("#id_theme").select2({width: 283, placeholder: 'Тематики'});
$("#id_country").select2({width: 283, placeholder: 'Страны'});
$("#id_area").select2({width: 283, placeholder: 'Географическая зона'});
var get_param = window.location.search;
if (!get_param) {
$('.toggled').collapse('hide');
}
$('legend').on('click', function () {
$('.toggled').collapse('toggle');
});
$('#export').on('click', function(event){
event.preventDefault();
window.location = "{% url 'export_contacts' %}" + get_param;
})
})
</script>
{% endblock %}
Loading…
Cancel
Save