--- /dev/null
+from django import forms
+
+
+class VisitsForm(forms.Form):
+ date_since = forms.DateField(required=False)
+ date_until = forms.DateField(required=False)
--- /dev/null
+{% extends 'base/base.html' %}
+
+
+{% block body %}
+ <div class="white-box">
+ {{ form.as_p }}
+ <hr>
+
+ <table>
+ <tr>
+ <th>Książka</th>
+ <th>Unikalne odsłony</th>
+ <th>Odsłony</th>
+ </tr>
+ {% for v in visits %}
+ <tr>
+ <td>
+ <a href="/katalog/lektura/{{ v.book__slug }}/">
+ {{ v.book__slug }}
+ </a>
+ </td>
+ <td>
+ {{ v.unique_views }}
+ </td>
+ <td>
+ {{ v.views }}
+ </td>
+ </tr>
+ {% endfor %}
+ </table>
+ </div>
+{% endblock %}
--- /dev/null
+from django.urls import path
+from . import views
+
+
+urlpatterns = [
+ path('top/', views.TopView.as_view(), name='stats_top'),
+]
--- /dev/null
+from django.contrib.auth.mixins import PermissionRequiredMixin
+from django.views.generic import TemplateView
+from django.db.models import Sum
+from . import forms
+from . import models
+
+
+class TopView(PermissionRequiredMixin, TemplateView):
+ permission_required = 'stats.view_visits'
+ template_name = 'stats/top.html'
+
+ def get_context_data(self, **kwargs):
+ ctx = super().get_context_data(**kwargs)
+ form = forms.VisitsForm(self.request.GET)
+ assert form.is_valid()
+ visits = models.Visits.objects.all()
+ if form.cleaned_data['date_since']:
+ visits = visits.filter(date__gte=form.cleaned_data['date_since'].replace(day=1))
+ if form.cleaned_data['date_until']:
+ visits = visits.filter(date__lte=form.cleaned_data['date_until'])
+ visits = visits.values('book__slug').annotate(
+ views=Sum('views'),
+ unique_views=Sum('unique_views')
+ )
+ visits = visits.order_by('-unique_views')
+ ctx['form'] = form
+ ctx['visits'] = visits
+ return ctx
+
path('isbn/', include('isbn.urls')),
path('messaging/', include('messaging.urls')),
path('re/', include('redirects.urls')),
+ path('stats/', include('stats.urls')),
path('paypal/app-form/', RedirectView.as_view(
url='/towarzystwo/?pk_campaign=aplikacja', permanent=False)),