From d7b0973ca3b454d6ec1c5db237a86b5a9dd70a49 Mon Sep 17 00:00:00 2001 From: Alexander Burdeiny Date: Tue, 19 Jul 2016 12:44:21 +0300 Subject: [PATCH] =?UTF-8?q?1457:=20=D0=AD=D1=82=D0=B0=D0=BF=20=E2=84=965:?= =?UTF-8?q?=20=D0=A1=D0=BE=20=D1=81=D0=BA=D0=B0=D0=B9=D0=BF=D0=B0=20-=20?= =?UTF-8?q?=D0=98=D0=BC=D0=BF=D0=BE=D1=80=D1=82=20=D0=BF=D0=BE=D0=B4=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D1=87=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- emencia/django/newsletter/admin_forms.py | 74 ++++++++++++++----- emencia/django/newsletter/admin_urls.py | 1 + emencia/django/newsletter/utils/excel.py | 66 ++++++++--------- .../django/newsletter/views/admin_views.py | 49 ++++++------ templates/admin/newsletters/contact_list.html | 7 +- .../newsletters/mailing_list_object.html | 23 +++++- 6 files changed, 142 insertions(+), 78 deletions(-) diff --git a/emencia/django/newsletter/admin_forms.py b/emencia/django/newsletter/admin_forms.py index ca7fa9f5..af046d25 100644 --- a/emencia/django/newsletter/admin_forms.py +++ b/emencia/django/newsletter/admin_forms.py @@ -70,9 +70,12 @@ class ContactSettingsForm(forms.ModelForm): class MailingListForm(forms.ModelForm): + theme_choices = [(item.id, item.name) for item in Theme.objects.language().all()] excel_file = forms.FileField(label=_(u'Импортировать подписчиков'), required=False) + add_from_themes = forms.MultipleChoiceField(label=_(u'Добавить подписчиков по тематикам'), required=False, + choices=theme_choices) theme_for_filter = forms.MultipleChoiceField(label=_(u'Тематики'), required=False, - choices=[(item.id, item.name) for item in Theme.objects.language().all()]) + choices=theme_choices) class Meta: model = MailingList @@ -80,25 +83,60 @@ class MailingListForm(forms.ModelForm): def save(self, commit=True): ml = super(MailingListForm, self).save(commit=True) - data = self.cleaned_data - f = data['excel_file'] - if f: - contact_list = list(Contact.objects.all()) - book = xlrd.open_workbook(file_contents=f.read()) - sheet = book.sheet_by_index(0) - excel_emails = {sheet.row_values(row_number)[0]: sheet.row_values(row_number)[1] for row_number in range(1, sheet.nrows)} - valid_contacts = [] - # for contact in contact_list: - # if contact.email in excel_emails: - # valid_contacts.append(contact) - for email, first_name in excel_emails.iteritems(): - valid_contacts.append(Contact.objects.create( - email=email, first_name=first_name, - valid=True, activated=True)) - ml.subscribers = valid_contacts - ml.save() + # data = self.cleaned_data + # f = data['excel_file'] + # if f: + # # contact_list = list(Contact.objects.all()) + # book = xlrd.open_workbook(file_contents=f.read()) + # sheet = book.sheet_by_index(0) + # excel_emails = {sheet.row_values(row_number)[0]: sheet.row_values(row_number)[1] for row_number in range(1, sheet.nrows)} + # valid_contacts = [] + # # for contact in contact_list: + # # if contact.email in excel_emails: + # # valid_contacts.append(contact) + # for email, first_name in excel_emails.iteritems(): + # valid_contacts.append(Contact.objects.create( + # email=email, first_name=first_name, + # valid=True, activated=True)) + # ml.subscribers = valid_contacts + # ml.save() return ml + def get_contact_list(self, qs): + excel_file = self.cleaned_data['excel_file'] + contact_items = dict(qs.values_list('email', 'pk')) + if excel_file: + book = xlrd.open_workbook(file_contents=excel_file.read()) + sheet = book.sheet_by_index(0) + for i in range(1, sheet.nrows): + email = sheet.row_values(i)[0] + first_name = sheet.row_values(i)[1] + exponent_practicum = sheet.row_values(i)[2] + organiser_practicum = sheet.row_values(i)[3] + if email not in contact_items: + try: + c = Contact.objects.get(email=email) + c.contactsettings.exponent_practicum = exponent_practicum + c.contactsettings.organiser_practicum = organiser_practicum + c.contactsettings.save() + except Contact.DoesNotExist: + c = Contact.objects.create(email=email, first_name=first_name, activated=True) + cs = ContactSettings( + contact=c, + exponent_practicum=exponent_practicum, + organiser_practicum=organiser_practicum, + ) + cs.save() + contact_items[email] = c.pk + ids = set(contact_items.values()) + if self.cleaned_data['add_from_themes']: + ct_from_themes = Contact.objects\ + .filter( + contactsettings__theme__in=self.cleaned_data['add_from_themes'] + ).distinct().values_list('pk', flat=True) + ids.update(ct_from_themes) + return ids + class NewsletterForm(forms.ModelForm): test_contacts = forms.ModelMultipleChoiceField(label=_(u'Тестовые контакты'), required=False, diff --git a/emencia/django/newsletter/admin_urls.py b/emencia/django/newsletter/admin_urls.py index fb1b2f9e..20cabb3d 100644 --- a/emencia/django/newsletter/admin_urls.py +++ b/emencia/django/newsletter/admin_urls.py @@ -40,6 +40,7 @@ urlpatterns = patterns('', url(r'^mailinglist/all/$', MailingListView.as_view(), name='newsletters_mailinglist'), url(r'^mailinglist/(?P\d+)/edit/', UpdateMailingList.as_view(), name='newsletters_mailinglist_update'), url(r'^mailinglist/(?P\d+)/', DeleteMailingList.as_view(), name='newsletters_mailinglist_delete'), + url(r'^mailinglist/filter/', CreateMailingList.as_view(), {'filter': True}, name='newsletters_mailinglist_create_filter'), url(r'^mailinglist/', CreateMailingList.as_view(), name='newsletters_mailinglist_create'), url(r'^contact/(?P\d+)/edit/', UpdateContact.as_view(), name='newsletters_contact_update'), diff --git a/emencia/django/newsletter/utils/excel.py b/emencia/django/newsletter/utils/excel.py index be226f00..1ccaf003 100644 --- a/emencia/django/newsletter/utils/excel.py +++ b/emencia/django/newsletter/utils/excel.py @@ -2,55 +2,53 @@ """ExcelResponse for emencia.django.newsletter""" # Based on http://www.djangosnippets.org/snippets/1151/ import datetime - -from django.http import HttpResponse -from django.db.models.query import QuerySet -from django.db.models.query import ValuesQuerySet # from ..models import ContactSettings from collections import OrderedDict -from functions.translate import fill_trans_fields_r + +from django.db.models.query import QuerySet, ValuesQuerySet +from django.http import HttpResponse, HttpResponseRedirect + from theme.models import Theme +from city.models import City +from country.models import Country, Area +from functions.translate import fill_trans_fields_r + +from ..models import ContactSettings class ExcelResponse(HttpResponse): """ExcelResponse feeded by queryset""" - - def __init__(self, data, output_name='excel_data', headers=None, sheet_name = "Sheet1", default_style=None, + def __init__(self, request, data, output_name='excel_data', headers=None, sheet_name = "Sheet1", default_style=None, force_csv=False, encoding='utf8'): + self.request = request valid_data = False - qs = data.prefetch_related('contactsettings', 'contactsettings__theme', 'contactsettings__area') - # if isinstance(data, ValuesQuerySet): - # data = list(data) - # elif isinstance(data, QuerySet): - # data = list(data.values()) - - # print(data) - # if 'settings' in headers: + contact_ids = list(data.values_list('pk', flat=True)) + qs = ContactSettings.objects.filter(contact_id__in=contact_ids) + if not qs.count(): + return HttpResponseRedirect(self.request.META['HTTP_REFERER']) + qs = qs.prefetch_related( + 'contact', 'theme', 'area', 'city', 'country', + ) data = [] + areas = dict(Area.objects.language('ru').all().values_list('pk', 'name')) + countries = dict(Country.objects.language('ru').all().values_list('pk', 'name')) + cities = dict(City.objects.language('ru').all().values_list('pk', 'name')) themes = dict(Theme.objects.language('ru').all().values_list('pk', 'name')) for item in qs: data.append([ - item.email, - item.first_name, - item.contactsettings.exponent_practicum, - item.contactsettings.organiser_practicum, - item.creation_date.strftime('%d.%m.%Y'), - item.modification_date.strftime('%d.%m.%Y'), - ', '.join([getattr(fill_trans_fields_r(obj=x, lang='ru'), 'name', '') for x in item.contactsettings.area.all()]), - ', '.join([themes.get(x.pk) for x in item.contactsettings.theme.all()]), + item.contact.email, + item.contact.first_name, + item.exponent_practicum, + item.organiser_practicum, + ', '.join([areas.get(x) for x in set(item.area.values_list('pk', flat=True))]), + ', '.join([countries.get(x) for x in set(item.country.values_list('pk', flat=True))]), + ', '.join([cities.get(x) for x in set(item.city.values_list('pk', flat=True))]), + ', '.join([themes.get(x) for x in set(item.theme.values_list('pk', flat=True))]), + item.contact.creation_date.strftime('%d.%m.%Y'), + item.contact.modification_date.strftime('%d.%m.%Y'), ]) - headers = ('email', 'first_name', 'приактикум экспонента', 'практикум организатор', 'дата подписки', 'дата изменения', 'гео', 'темы') - - - # if hasattr(data, '__getitem__'): - # if isinstance(data[0], dict): - # if headers is None: - # headers = data[0].keys() - # data = [[row[col] for col in headers] for row in data] + headers = ('email', 'first_name', 'приактикум экспонента', 'практикум организатор', 'гео', 'страна', 'город', 'темы', 'дата подписки', 'дата изменения') data.insert(0, headers) - # if hasattr(data[0], '__getitem__'): - # valid_data = True - # assert valid_data is True, "ExcelResponse requires a sequence of sequences" import StringIO output = StringIO.StringIO() diff --git a/emencia/django/newsletter/views/admin_views.py b/emencia/django/newsletter/views/admin_views.py index 66f293cc..47e0cda8 100644 --- a/emencia/django/newsletter/views/admin_views.py +++ b/emencia/django/newsletter/views/admin_views.py @@ -144,7 +144,7 @@ class ExportContacts(FormView): qs, title = form.filter() if qs.count(): columns = ('email', 'first_name') - return ExcelResponse(qs, title, columns,'contacts') + return ExcelResponse(request, qs, title, columns,'contacts') return HttpResponseRedirect(self.request.META['HTTP_REFERER']) @@ -170,42 +170,47 @@ class DeleteMailingList(DeleteView): success_url = reverse_lazy('newsletters_mailinglist') -class UpdateMailingList(UpdateView): +class MailingListMixin(object): model = MailingList form_class = MailingListForm template_name = 'admin/newsletters/mailing_list_object.html' success_url = '/admin/newsletters/mailinglist/all/' - def get_success_url(self): - return self.success_url + def dispatch(self, request, *args, **kwargs): + self.filter = kwargs.get('filter', False) + return super(MailingListMixin, self).dispatch(request, *args, **kwargs) def form_valid(self, form): + filter_form = ContactFilterForm(self.request.GET) + if not self.object: + contacts = Contact.objects.none() + if self.filter and filter_form.is_valid(): + contacts, _ = filter_form.filter() + else: + contacts = self.object.subscribers.all() obj = form.save() - - themes = form.cleaned_data.get('theme_for_filter') - if themes: - obj.subscribers.add(*list(Contact.objects.filter(contactsettings__theme__in=themes).distinct())) - + obj.subscribers = form.get_contact_list(contacts) return HttpResponseRedirect(self.success_url) + def get_context_data(self, **kwargs): + context = super(MailingListMixin, self).get_context_data(**kwargs) + form = ContactFilterForm(self.request.GET) -class CreateMailingList(CreateView): - model = MailingList - form_class = MailingListForm - template_name = 'admin/newsletters/mailing_list_object.html' - success_url = '/admin/newsletters/mailinglist/all/' + context['filter_form'] = form + if form.is_valid(): + qs, _ = form.filter() + context['contact_count'] = qs.count() + context['filter_params'] = self.filter + return context - def form_valid(self, form): - obj = form.save() - # filter_form = ContactFilterForm(self.request.GET) - # if filter_form.is_valid(): - # contacts, _ = filter_form.filter() - # obj.subscribers = contacts - # obj.save() +class CreateMailingList(MailingListMixin, CreateView): + pass - return HttpResponseRedirect(self.success_url) + +class UpdateMailingList(MailingListMixin, UpdateView): + pass class NewsletterCreate(CreateView): diff --git a/templates/admin/newsletters/contact_list.html b/templates/admin/newsletters/contact_list.html index 8f72d671..ad149c71 100644 --- a/templates/admin/newsletters/contact_list.html +++ b/templates/admin/newsletters/contact_list.html @@ -120,7 +120,8 @@ @@ -199,9 +200,9 @@ event.preventDefault(); window.location = "{% url 'export_contacts' %}" + get_param; }); - $('#mailinglist').on('click', function(event){ + $('a#mailinglist').on('click', function(event){ event.preventDefault(); - window.location = "{% url 'newsletters_mailinglist_create' %}" + get_param; + window.location = $(this).attr('href') + get_param; }); $('#id_created_from').datetimepicker({ todayHighlight: true, diff --git a/templates/admin/newsletters/mailing_list_object.html b/templates/admin/newsletters/mailing_list_object.html index 91c26b3e..f9928164 100644 --- a/templates/admin/newsletters/mailing_list_object.html +++ b/templates/admin/newsletters/mailing_list_object.html @@ -1,5 +1,6 @@ {% extends 'admin/base.html' %} {% load static %} +{% load i18n %} {% block body %} @@ -8,8 +9,28 @@
-

{% if object %}Изменения{% else %}Создание{% endif %} списка рассылок

+

{% if object %}{% trans "Изменение" %}{% else %}{% trans "Создание" %}{% endif %} {% trans "списка рассылок" %}

+ {% if filter_params %} + {% if not filter_form.errors %} + + {% else %} + + {% endif %} + {% endif %} + {% if form.instance.pk %} + + {% endif %}
{% for field in form %}