From c9bf6da34b8fa94d191858389e4d4a21e7b3c48c Mon Sep 17 00:00:00 2001 From: Alexander Burdeiny Date: Thu, 21 Apr 2016 11:40:51 +0300 Subject: [PATCH] =?UTF-8?q?1241:=20=D0=A1=D1=82=D0=B0=D1=82=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D0=BA=D0=B0=20=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D0=B5=D0=B9=20=D0=B2=20=D0=B0?= =?UTF-8?q?=D0=B4=D0=BC=D0=B8=D0=BD=D0=BA=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- accounts/admin.py | 143 ++++++++++++++++++++++-- accounts/admin_urls.py | 3 +- accounts/models.py | 12 +- company/models.py | 7 +- static/admin/css/base.css | 1 - templates/admin/accounts/user_stat.html | 70 ++++++++++++ templates/admin/includes/admin_nav.html | 7 +- 7 files changed, 219 insertions(+), 24 deletions(-) create mode 100644 templates/admin/accounts/user_stat.html diff --git a/accounts/admin.py b/accounts/admin.py index c57134a5..fd3ac63f 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -1,26 +1,41 @@ # -*- coding: utf-8 -*- -import random +import datetime import json +import random +from datetime import date from hashlib import md5 -from django.shortcuts import render_to_response + +from company.models import Company from django.conf import settings -from django.http import HttpResponseRedirect, HttpResponse -from django.core.context_processors import csrf from django.contrib.auth.decorators import login_required +from django.core.context_processors import csrf +from django.core.exceptions import ImproperlyConfigured +from django.http import HttpResponse, HttpResponseRedirect +from django.shortcuts import render_to_response +from django.utils import timezone from django.utils.translation import ugettext as _ -#models and forms -from models import User -from forms import UserForm, UserCreationForm, ChangePasswordForm, EmailAnnouncementForm, UserFilterForm -#custom views -from django.views.generic import UpdateView, DeleteView -from functions.admin_views import AdminView, AdminListView, paginate_results +from django.views.generic import DeleteView, TemplateView, UpdateView +from django.views.generic.dates import DateMixin, MonthMixin, YearMixin +from forms import ( + ChangePasswordForm, + EmailAnnouncementForm, + UserCreationForm, + UserFilterForm, + UserForm +) +# custom views +from functions.admin_views import AdminListView, AdminView, paginate_results + +# models and forms +from .models import User class DeleteAccount(DeleteView): model = User success_url = '/admin/accounts/all/' + class UserListView(AdminListView): template_name = 'admin/accounts/user_list.html' form_class = UserFilterForm @@ -33,6 +48,7 @@ class UserListView(AdminListView): context['object_list'] = result return context + class EditUser(UpdateView): model = User form_class = UserForm @@ -40,7 +56,6 @@ class EditUser(UpdateView): template_name = 'user_change.html' - def user_change(request, url): """ Return form of user and post it on the server. @@ -153,7 +168,6 @@ def generatePassword(): return ''.join(newPassword) - def reset_password_email(request): """ generate random password @@ -169,6 +183,7 @@ def reset_password_email(request): return HttpResponse('error') + @login_required def change_password(request): """ @@ -196,3 +211,107 @@ def change_password(request): return HttpResponse(json.dumps(success), content_type='application/json') else: return HttpResponse(json.dumps(success), content_type='application/json') + + +class AccountsStatistic(TemplateView, YearMixin, MonthMixin, DateMixin): + queryset = None + model = User + template_name = 'admin/accounts/user_stat.html' + date_field = 'date_joined' + + def _get_prev_day(self, date=None): + """Return previous day of the given date. + """ + date = getattr(self, 'date', date) + return date - datetime.timedelta(days=1) + + def _get_prev_year(self, date): + """Return previous year of the given date. + """ + return date.replace(year=date.year - 1, month=1, day=1) + + def _get_prev_month(self, date): + """Return previous month of the given date. + """ + if date.month == 1: + return date.replace(year=date.year - 1, month=12, day=1) + else: + return date.replace(month=date.month - 1, day=1) + + def make_lookup_kwargs(self, since, until): + date_field = self.get_date_field() + lookup_kwargs = { + '%s__gte' % date_field: since, + '%s__lt' % date_field: until, + } + return lookup_kwargs + + def get_current_day_lookup(self): + return self._make_single_date_lookup(self.date) + + def get_prev_day_lookup(self): + return self._make_single_date_lookup(self._get_prev_day()) + + def get_current_month_lookup(self): + since = self._make_date_lookup_arg(self._get_current_month(self.date)) + until = self._make_date_lookup_arg(self._get_next_month(self.date)) + return self.make_lookup_kwargs(since, until) + + def get_prev_month_lookup(self): + since = self._make_date_lookup_arg(self._get_prev_month(self.date)) + until = self._make_date_lookup_arg(self._get_current_month(self.date)) + return self.make_lookup_kwargs(since, until) + + def get_current_year_lookup(self): + since = self._make_date_lookup_arg(self._get_current_year(self.date)) + until = self._make_date_lookup_arg(self._get_next_year(self.date)) + return self.make_lookup_kwargs(since, until) + + def get_prev_year_lookup(self): + since = self._make_date_lookup_arg(self._get_prev_year(self.date)) + until = self._make_date_lookup_arg(self._get_current_year(self.date)) + return self.make_lookup_kwargs(since, until) + + def get_queryset(self): + """ + Get the queryset to look an object up against. May not be called if + `get_object` is overridden. + """ + if self.queryset is None: + if self.model: + return self.model._default_manager.all() + else: + raise ImproperlyConfigured("%(cls)s is missing a queryset. Define " + "%(cls)s.model, %(cls)s.queryset, or override " + "%(cls)s.get_queryset()." % { + 'cls': self.__class__.__name__ + }) + return self.queryset._clone() + + def get_qs_count(self, lookup_kwargs): + return self.queryset.filter(**lookup_kwargs).count() + + def get(self, request, *args, **kwargs): + self.date = date.today() + self.year = self.date.year + self.month = self.date.month + return super(AccountsStatistic, self).get(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + self.queryset = self.get_queryset() + context = super(AccountsStatistic, self).get_context_data(**kwargs) + context['accounts_overall'] = self.queryset.count() + context['companies_overall'] = Company.objects.count() + context['current_day'] = \ + self.get_qs_count(self.get_current_day_lookup()) + context['prev_day'] = \ + self.get_qs_count(self.get_prev_day_lookup()) + context['current_month'] = \ + self.get_qs_count(self.get_current_month_lookup()) + context['prev_month'] = \ + self.get_qs_count(self.get_prev_month_lookup()) + context['current_year'] = \ + self.get_qs_count(self.get_current_year_lookup()) + context['prev_year'] = \ + self.get_qs_count(self.get_prev_year_lookup()) + return context diff --git a/accounts/admin_urls.py b/accounts/admin_urls.py index 2f8bbcd8..6a381787 100644 --- a/accounts/admin_urls.py +++ b/accounts/admin_urls.py @@ -3,7 +3,7 @@ from django.conf.urls import patterns, url from django.core.urlresolvers import reverse_lazy from functions.custom_views import SimpleObjectChangeView -from .admin import DeleteAccount, EditUser, UserListView +from .admin import AccountsStatistic, DeleteAccount, EditUser, UserListView from .models import User attrs = { @@ -13,6 +13,7 @@ attrs = { } urlpatterns = patterns('', + url(r'^statistic/$', AccountsStatistic.as_view(), name='admin_accounts_statistic'), url(r'^change/(?P.*)/$', 'accounts.admin.user_change'), url(r'^all/$', UserListView.as_view(), name='admin_accounts_all'), url(r'^reset_password_email/$', 'accounts.admin.reset_password_email'), diff --git a/accounts/models.py b/accounts/models.py index a226017a..413b9560 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -1,12 +1,16 @@ # -*- coding: utf-8 -*- +from django.contrib.auth.models import ( + AbstractBaseUser, + BaseUserManager, + PermissionsMixin +) +from django.core.mail import send_mail from django.db import models from django.db.models import Q -from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin -from django.core.mail import send_mail +from django.db.models.loading import get_model +from django.db.models.signals import post_save from django.utils import timezone from django.utils.translation import ugettext as _ -from django.db.models.signals import post_save -from django.db.models.loading import get_model from functions.form_check import translit_with_separator from functions.model_mixin import GetURLorPK diff --git a/company/models.py b/company/models.py index 536c7780..81e5f3d0 100644 --- a/company/models.py +++ b/company/models.py @@ -1,15 +1,16 @@ # -*- coding: utf-8 -*- import os + +from django.contrib.contenttypes import generic from django.db import models from django.db.models.signals import post_save -from hvad.models import TranslatableModel, TranslatedFields, TranslationManager -from django.contrib.contenttypes import generic from django.utils import translation from django.utils.translation import ugettext as _ from functions.custom_fields import LocationField -from functions.models_methods import ExpoManager from functions.model_mixin import ExpoMixin, GetURLorPK +from functions.models_methods import ExpoManager from functions.signal_handlers import post_save_handler +from hvad.models import TranslatableModel, TranslatedFields, TranslationManager def get_storage_path(instance, filename): diff --git a/static/admin/css/base.css b/static/admin/css/base.css index 5ac4032c..489bfe5b 100644 --- a/static/admin/css/base.css +++ b/static/admin/css/base.css @@ -836,4 +836,3 @@ table#change-history tbody th { background: #eee url(../img/nav-bg.gif) bottom left repeat-x; color: #666; } - diff --git a/templates/admin/accounts/user_stat.html b/templates/admin/accounts/user_stat.html new file mode 100644 index 00000000..28efea34 --- /dev/null +++ b/templates/admin/accounts/user_stat.html @@ -0,0 +1,70 @@ +{% extends 'admin/base.html' %} +{% load staticfiles %} + +{% block styles %} + .blank_row { + height: 35px !important; /* Overwrite any previous rules */ + background-color: #FFFFFF; + } +{% endblock styles %} + +{% block body %} +
+
+

Статистика пользователей

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Всего зарегистрировано
аккаунтов{{ accounts_overall }}
страниц компаний{{ companies_overall }}
За сегодня{{ current_day }}
За вчера{{ prev_day }}
За текущий месяц{{ current_month }}
За прошлый месяц{{ prev_month }}
За текущий год{{ current_year }}
За прошлый год{{ prev_year }}
+
+
+{% endblock %} + diff --git a/templates/admin/includes/admin_nav.html b/templates/admin/includes/admin_nav.html index a7eb0250..1b0347e3 100644 --- a/templates/admin/includes/admin_nav.html +++ b/templates/admin/includes/admin_nav.html @@ -28,9 +28,10 @@
  • Статистика
  • + @@ -116,7 +117,7 @@
  • Подписчики
  • Списки рассылок
  • Рассылки
  • -
  • Статистика
  • +
  • Статистика