Newsletter history

remotes/origin/1203
Nazar Kotjuk 10 years ago
parent deee703a55
commit 1672162a22
  1. 23
      emencia/django/newsletter/forms.py
  2. 83
      emencia/django/newsletter/views/admin_views.py
  3. 13
      templates/admin/newsletters/newsletter_history.html
  4. 11
      templates/admin/newsletters/newsletter_stat.html

@ -2,6 +2,7 @@
"""Forms for emencia.django.newsletter""" """Forms for emencia.django.newsletter"""
from datetime import datetime, date, timedelta from datetime import datetime, date, timedelta
from django import forms from django import forms
from django.db.models import Sum
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.http import Http404 from django.http import Http404
@ -9,7 +10,7 @@ from django.core.exceptions import ValidationError
from django.utils import translation from django.utils import translation
from haystack.query import SearchQuerySet from haystack.query import SearchQuerySet
from functions.search_forms import get_by_lang from functions.search_forms import get_by_lang
from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, PopupCount from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, PopupCount, ContactMailingStatus
from functions.form_check import translit_with_separator as tr 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
@ -336,7 +337,7 @@ class SubscribeSettingsForm(AbstractSubscribeForm):
def clean_email(self): def clean_email(self):
return self.cleaned_data['email'] return self.cleaned_data['email']
from django.db.models import Sum
class PopupCountFilter(forms.Form): class PopupCountFilter(forms.Form):
fr = forms.DateField(required=False) fr = forms.DateField(required=False)
to = forms.DateField(required=False) to = forms.DateField(required=False)
@ -358,4 +359,20 @@ class PopupCountFilter(forms.Form):
activated = contacts.filter(activated=True).count() activated = contacts.filter(activated=True).count()
popups = qs.aggregate(count=Sum('cnt'))['count'] popups = qs.aggregate(count=Sum('cnt'))['count']
return {'subscribed': subscribed, 'activated': activated, 'popups': popups} return {'subscribed': subscribed, 'activated': activated, 'popups': popups}
class MailingStatusFilter(forms.Form):
status = forms.ChoiceField(choices=[('', u'Не выбрано')] + [(item[0], item[1]) for item in ContactMailingStatus.STATUS_CHOICES],
required=False)
email = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': 'Email'}))
def filter(self, newsletter):
status = self.cleaned_data.get('status')
email = self.cleaned_data.get('email')
qs = ContactMailingStatus.objects.select_related().filter(newsletter=newsletter)
if status:
qs = qs.filter(status=status)
if email:
qs = qs.filter(contact__email=email)
return qs

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import datetime
from django.views.generic import CreateView, ListView, UpdateView, DeleteView, FormView, DetailView, RedirectView, TemplateView from django.views.generic import CreateView, ListView, UpdateView, DeleteView, FormView, DetailView, RedirectView, TemplateView
from django.conf import settings from django.conf import settings
from django.utils import translation from django.utils import translation
@ -7,14 +8,17 @@ from django.forms.formsets import formset_factory
from django.http import HttpResponseRedirect, HttpResponse 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_lazy from django.core.urlresolvers import reverse_lazy
from django.forms.models import modelformset_factory
from HTMLParser import HTMLParseError from HTMLParser import HTMLParseError
from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, Newsletter, Attachment, ContactMailingStatus from emencia.django.newsletter.models import Contact, ContactSettings, MailingList, Newsletter, Attachment, ContactMailingStatus
from emencia.django.newsletter.admin_forms import ContactSettingsForm, MailingListForm, NewsletterForm, AttachmentForm from emencia.django.newsletter.admin_forms import ContactSettingsForm, MailingListForm, NewsletterForm, AttachmentForm
from emencia.django.newsletter.mailer import Mailer from emencia.django.newsletter.mailer import Mailer
from emencia.django.newsletter.forms import PopupCountFilter from emencia.django.newsletter.forms import PopupCountFilter, MailingStatusFilter
from ..forms import ContactFilterForm, ContactImportForm from ..forms import ContactFilterForm, ContactImportForm
from ..utils.excel import ExcelResponse from ..utils.excel import ExcelResponse
from functions.admin_views import paginate_results from functions.admin_views import paginate_results
from ..models import PopupCount
from theme.models import Theme
class ContactList(FormView): class ContactList(FormView):
@ -71,8 +75,6 @@ class ContactQueryDelete(RedirectView):
return HttpResponse('400') return HttpResponse('400')
class DeleteContact(DeleteView): class DeleteContact(DeleteView):
model = Contact model = Contact
success_url = reverse_lazy('newsletters_contact_list') success_url = reverse_lazy('newsletters_contact_list')
@ -128,8 +130,6 @@ class ImportContacts(FormView):
return HttpResponseRedirect(self.get_success_url()) return HttpResponseRedirect(self.get_success_url())
class MailingListView(ListView): class MailingListView(ListView):
paginate_by = settings.ADMIN_PAGINATION paginate_by = settings.ADMIN_PAGINATION
model = MailingList model = MailingList
@ -167,8 +167,6 @@ class CreateMailingList(CreateView):
obj.save() obj.save()
return HttpResponseRedirect(self.success_url) return HttpResponseRedirect(self.success_url)
from django.forms.models import modelformset_factory
class NewsletterCreate(CreateView): class NewsletterCreate(CreateView):
model = Newsletter model = Newsletter
@ -241,7 +239,6 @@ class NewsletterUpdate(UpdateView):
return HttpResponseRedirect(self.success_url) return HttpResponseRedirect(self.success_url)
class NewsletterListView(ListView): class NewsletterListView(ListView):
paginate_by = settings.ADMIN_PAGINATION paginate_by = settings.ADMIN_PAGINATION
model = Newsletter model = Newsletter
@ -272,21 +269,25 @@ class NewsletterStatistics(DetailView):
context = super(NewsletterStatistics, self).get_context_data(**kwargs) context = super(NewsletterStatistics, self).get_context_data(**kwargs)
sent = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.SENT).count() sent = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.SENT).count()
errors = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.ERROR).count() errors = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.ERROR).count()
opened = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.OPENED).count() opened = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.OPENED).\
values_list('contact', flat=True).distinct().count()
unsubscribed = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.UNSUBSCRIPTION).\ unsubscribed = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.UNSUBSCRIPTION).\
values_list('contact', flat=True).distinct().count() values_list('contact', flat=True).distinct().count()
no_data = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.ANNOUNCE_NO_DATA).count() no_data = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.ANNOUNCE_NO_DATA).count()
links = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.LINK_OPENED).count() links = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.LINK_OPENED).count()
links_unique = self.object.contactmailingstatus_set.filter(status=ContactMailingStatus.LINK_OPENED).\
values_list('contact', flat=True).distinct().count()
CMS = ContactMailingStatus CMS = ContactMailingStatus
opened_percent = 0 if opened or sent == 0 else (float(opened)/sent)*100 opened_percent = 0 if opened or sent == 0 else (float(opened)/sent)*100
unsub_percent = 0 if unsubscribed or sent == 0 else (float(unsubscribed)/sent)*100 unsub_percent = 0 if unsubscribed or sent == 0 else (float(unsubscribed)/sent)*100
stat = { stat = {
'sent':{'data':sent, 'filter':""}, 'sent': {'data': sent, 'filter': ""},
'errors':{ 'data':errors, 'filter':CMS.ERROR}, 'errors': {'data': errors, 'filter': CMS.ERROR},
'opened':{'data': opened, 'filter': CMS.OPENED, 'percent': opened_percent}, 'opened': {'data': opened, 'filter': CMS.OPENED, 'percent': opened_percent},
'unsub':{'data': unsubscribed, 'filter': CMS.UNSUBSCRIPTION, 'percent': unsub_percent}, 'unsub': {'data': unsubscribed, 'filter': CMS.UNSUBSCRIPTION, 'percent': unsub_percent},
'no_data':{'data': no_data, 'filter': CMS.ANNOUNCE_NO_DATA}, 'no_data': {'data': no_data, 'filter': CMS.ANNOUNCE_NO_DATA},
'links':{'data': links, 'filter': CMS.LINK_OPENED}} 'links': {'data': links, 'filter': CMS.LINK_OPENED},
'links_unique': {'data': links_unique, 'filter': CMS.LINK_OPENED}}
context.update({'stat': stat}) context.update({'stat': stat})
return context return context
@ -310,33 +311,36 @@ class NewsletterHistory(ListView):
def get_queryset(self): def get_queryset(self):
self.newsletter = get_object_or_404(Newsletter, pk=self.kwargs['pk']) self.newsletter = get_object_or_404(Newsletter, pk=self.kwargs['pk'])
qs = self.newsletter.contactmailingstatus_set.select_related('contact', 'link').all() if self.request.GET:
if self.request.GET.get('filter'): form = MailingStatusFilter(self.request.GET)
qs = qs.filter(status=self.request.GET['filter']) if form.is_valid():
qs = form.filter(self.newsletter)
else:
qs = ContactMailingStatus.objects.select_related().filter(newsletter=self.newsletter)
else:
qs = ContactMailingStatus.objects.select_related().filter(newsletter=self.newsletter)
return qs return qs
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(NewsletterHistory, self).get_context_data(**kwargs) context = super(NewsletterHistory, self).get_context_data(**kwargs)
context['newsletter'] = self.newsletter context['newsletter'] = self.newsletter
context['choices'] = ContactMailingStatus.STATUS_CHOICES context['choices'] = ContactMailingStatus.STATUS_CHOICES
form = MailingStatusFilter(self.request.GET)
context['filter_form'] = form
return context return context
class NewsletterDelete(DeleteView): class NewsletterDelete(DeleteView):
model = Newsletter model = Newsletter
template_name = 'admin/newsletters/confirm_delete.html' template_name = 'admin/newsletters/confirm_delete.html'
success_url = reverse_lazy('newsletters_newsletters_list') success_url = reverse_lazy('newsletters_newsletters_list')
import datetime
from ..models import PopupCount
from theme.models import Theme
def count_popups(request): def count_popups(request):
#if not request.is_ajax(): if not request.is_ajax():
# return HttpResponse("request is not ajax") return HttpResponse("request is not ajax")
#else: else:
themes = request.GET.getlist('theme') themes = request.GET.getlist('theme')
if themes: if themes:
for theme_id in themes: for theme_id in themes:
@ -350,8 +354,6 @@ def count_popups(request):
return HttpResponse(obj.cnt, content_type='application/json') return HttpResponse(obj.cnt, content_type='application/json')
class PopupStatisticsView(FormView): class PopupStatisticsView(FormView):
form_class = PopupCountFilter form_class = PopupCountFilter
template_name = 'admin/newsletters/popup_count.html' template_name = 'admin/newsletters/popup_count.html'
@ -368,27 +370,4 @@ class PopupStatisticsView(FormView):
data = form.filter() data = form.filter()
data['form'] = form data['form'] = form
return self.render_to_response(data) return self.render_to_response(data)
"""
class PopupStatisticsView(TemplateView):
model = PopupCount
template_name = 'admin/newsletters/popup_count.html'
def get(self, request, *args, **kwargs):
qs = PopupCount.objects.all()
data = self.request.GET
if data.get('from'):
qs = qs.filter(date__gte=datetime.datetime.strptime(data['from'], '%d.%m.%Y').date())
if data.get('to'):
qs = qs.filter(date__lt=datetime.datetime.strptime(data['to'], '%d.%m.%Y').date())
if not data.get('from') and not data.get('to'):
qs = qs.filter(date=datetime.date.today())
if qs:
res = {'cnt':qs.aggregate(cnt=Sum('cnt'))['cnt'], 'subscr':qs[0].get_subscr(), 'active':qs[0].get_active()}
else:
res = {'cnt':0, 'subscr':0, 'active':0}
return self.render_to_response({'object':res})
"""

@ -8,14 +8,11 @@
</div> </div>
<div class="box-content"> <div class="box-content">
<form id="id_form" class="form-inline"> <form id="id_form" class="form-inline">
<div class="form-group"> <div class="form-group">
<select class="form-control" name="filter" id="filter"> {{ filter_form.status }}
<option>Фильтровать</option> {{ filter_form.email }}
<option value="">Все</option> <button type="submit" class="btn">Применить</button>
{% for id, name in choices%}
<option class="opt" value="{{ id }}">{{ name }}</option>
{% endfor %}
</select>
</div> </div>
</form> </form>
<table class="table table-hover table table-bordered table-striped"> <table class="table table-hover table table-bordered table-striped">
@ -44,7 +41,7 @@
</div> </div>
{# pagination #} {# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} {% include 'admin/includes/admin_pagination.html' with page_obj=page_obj %}
</div> </div>
<script> <script>
$(document).ready(function(){ $(document).ready(function(){

@ -33,12 +33,12 @@
</tr> </tr>
<tr> <tr>
<td>Открыто</td> <td>Открыто(уникальных)</td>
<td>{{ stat.opened.data }} {% if stat.opened.percent %} ({{ stat.opened.percent|floatformat:"0" }}%) {% endif %}</td> <td>{{ stat.opened.data }} {% if stat.opened.percent %} ({{ stat.opened.percent|floatformat:"0" }}%) {% endif %}</td>
<td><a href="{% url 'newsletters_newsletters_history' object.id %}?filter={{ stat.opened.filter }}">Подробно</a></td> <td><a href="{% url 'newsletters_newsletters_history' object.id %}?filter={{ stat.opened.filter }}">Подробно</a></td>
</tr> </tr>
<tr> <tr>
<td>Отписалось</td> <td>Отписалось(уникальных)</td>
<td>{{ stat.unsub.data }} {% if stat.unsub.percent %} ({{ stat.unsub.percent|floatformat:"0" }}%) {% endif %}</td> <td>{{ stat.unsub.data }} {% if stat.unsub.percent %} ({{ stat.unsub.percent|floatformat:"0" }}%) {% endif %}</td>
<td><a href="{% url 'newsletters_newsletters_history' object.id %}?filter={{ stat.unsub.filter }}">Подробно</a></td> <td><a href="{% url 'newsletters_newsletters_history' object.id %}?filter={{ stat.unsub.filter }}">Подробно</a></td>
</tr> </tr>
@ -48,11 +48,16 @@
<td>{{ stat.no_data.data }}</td> <td>{{ stat.no_data.data }}</td>
<td><a href="{% url 'newsletters_newsletters_history' object.id %}?filter={{ stat.no_data.filter }}">Подробно</a></td> <td><a href="{% url 'newsletters_newsletters_history' object.id %}?filter={{ stat.no_data.filter }}">Подробно</a></td>
</tr> </tr>
<tr> <tr>
<td>Переходов по ссылкам</td> <td>Переходов по ссылкам</td>
<td>{{ stat.links.data }}</td> <td>{{ stat.links.data }}</td>
<td><a href="{% url 'newsletters_newsletters_history' object.id %}?filter={{ stat.links.filter }}">Подробно</a></td> <td><a href="{% url 'newsletters_newsletters_history' object.id %}?filter={{ stat.links.filter }}">Подробно</a></td>
</tr> </tr>
<tr>
<td>Переходов уникальными пользователями</td>
<td>{{ stat.links_unique.data }}</td>
<td><a href="{% url 'newsletters_newsletters_history' object.id %}?filter={{ stat.links_unique.filter }}">Подробно</a></td>
</tr>
</tbody> </tbody>
</table> </table>

Loading…
Cancel
Save