From 70af5a29ccdfd34d9a75d877ab5c80d752413626 Mon Sep 17 00:00:00 2001 From: Ivan Kovalkovskyi Date: Fri, 16 Oct 2015 13:39:26 +0300 Subject: [PATCH] Import contacts for mailing list --- emencia/django/newsletter/admin_forms.py | 22 ++++++++++++++ emencia/django/newsletter/forms.py | 27 ++++++++++++++---- .../django/newsletter/views/admin_views.py | 15 ++++++---- static/admin/img/loader.GIF | Bin 0 -> 11357 bytes .../import templates/import_contacts.html | 19 ++++++++++-- 5 files changed, 70 insertions(+), 13 deletions(-) create mode 100644 static/admin/img/loader.GIF diff --git a/emencia/django/newsletter/admin_forms.py b/emencia/django/newsletter/admin_forms.py index a15c1667..703b6730 100644 --- a/emencia/django/newsletter/admin_forms.py +++ b/emencia/django/newsletter/admin_forms.py @@ -42,11 +42,33 @@ class ContactSettingsForm(forms.ModelForm): return City.objects.none() +import xlrd + + class MailingListForm(forms.ModelForm): + excel_file = forms.FileField(label='Импортировать подписчиков', required=False) + class Meta: model = MailingList fields = ('name', 'description') + 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] 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) + ml.subscribers = valid_contacts + ml.save() + return ml + class NewsletterForm(forms.ModelForm): test_contacts = forms.ModelMultipleChoiceField(label=u'Тестовые контакты', required=False, diff --git a/emencia/django/newsletter/forms.py b/emencia/django/newsletter/forms.py index 6b179779..83243ef5 100644 --- a/emencia/django/newsletter/forms.py +++ b/emencia/django/newsletter/forms.py @@ -2,6 +2,7 @@ """Forms for emencia.django.newsletter""" from django import forms from django.utils.translation import ugettext_lazy as _ +from django.http import Http404 from emencia.django.newsletter.models import Contact, ContactSettings from emencia.django.newsletter.models import MailingList @@ -169,9 +170,25 @@ class ContactImportForm(forms.Form): f = data['excel_file'] book = xlrd.open_workbook(file_contents=f.read()) sheet = book.sheet_by_index(0) - row_list = [sheet.row_values(row_number) for row_number in range(1,sheet.nrows)] - contact_list = [] + row_list = [sheet.row_values(row_number) for row_number in range(1, sheet.nrows)] for row in row_list: - contact_list.append(Contact(first_name=row[0], email=row[1], activated=activated, tester=is_tester)) - Contact.objects.bulk_create(contact_list) - Contact.objects.filter(first_name__in=[c[0] for c in contact_list]).update(contactsettings__country=country) + c = Contact(email = row[0], first_name=row[1].split()[0], last_name=row[1].split()[-1], tester=is_tester, + activated=activated, valid=True, subscriber=True) + try: + c.save() + except: + continue + cs = ContactSettings() + cs.contact = c + cs.save() + if country: + cs.country.add(country) + cs.save() + +# do not watch +# cursor = db.cursor() +# sql = u""" +# INSERT IGNORE +# INTO newsletter_contact(first_name, email, activated, tester, creation_date, last_name) +# VALUES %s;""" % u','.join([u"('%s', '%s', '%s', '%s', NOW(), '')" % (row[1], row[0], str(activated).upper(), str(is_tester).upper()) for row in row_list]) +# cursor.execute(sql) \ No newline at end of file diff --git a/emencia/django/newsletter/views/admin_views.py b/emencia/django/newsletter/views/admin_views.py index acec8ba3..9990820d 100644 --- a/emencia/django/newsletter/views/admin_views.py +++ b/emencia/django/newsletter/views/admin_views.py @@ -59,6 +59,7 @@ class DeleteContact(DeleteView): success_url = reverse_lazy('newsletters_contact_list') template_name = 'admin/newsletters/confirm_delete.html' + class UpdateContact(UpdateView): model = ContactSettings form_class = ContactSettingsForm @@ -99,6 +100,9 @@ class UpdateMailingList(UpdateView): template_name = 'admin/newsletters/mailing_list_object.html' success_url = '/admin/newsletters/mailinglist/all/' + def get_success_url(self): + return self.success_url + class CreateMailingList(CreateView): model = MailingList @@ -108,9 +112,9 @@ class CreateMailingList(CreateView): def form_valid(self, form): obj = form.save() - form = ContactFilterForm(self.request.GET) - if form.is_valid(): - contacts, _ = form.filter() + filter_form = ContactFilterForm(self.request.GET) + if filter_form.is_valid(): + contacts, _ = filter_form.filter() obj.subscribers = contacts obj.save() return HttpResponseRedirect(self.success_url) @@ -220,7 +224,7 @@ class ExportContacts(FormView): if form.is_valid(): qs, title = form.filter() if qs.count(): - columns = ('first_name', 'email') + columns = ('email', 'first_name') return ExcelResponse(qs, title, columns,'contacts') return HttpResponseRedirect(self.request.META['HTTP_REFERER']) @@ -232,4 +236,5 @@ class ImportContacts(FormView): def form_valid(self, form): form.save() - return HttpResponseRedirect(self.get_success_url()) \ No newline at end of file + return HttpResponseRedirect(self.get_success_url()) + diff --git a/static/admin/img/loader.GIF b/static/admin/img/loader.GIF new file mode 100644 index 0000000000000000000000000000000000000000..9c7b179fac46039a29f8cab74d889cc18bc5c1f1 GIT binary patch literal 11357 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
- +
- - {% endblock %} {% block scripts %} {% endblock %} +{% block styles %} +.loader { + position: fixed; + left: 0px; + top: 0px; + width: 100%; + height: 100%; + z-index: 9999; + background: url('{% static "admin/img/loader.GIF" %}') 50% 50% no-repeat rgb(249,249,249); +} +{% endblock %} \ No newline at end of file