From b20319c22709092e478c2869182304191dc85f87 Mon Sep 17 00:00:00 2001 From: Summon Agus Date: Thu, 3 Dec 2020 05:43:04 +0700 Subject: [PATCH] added dashboard app --- apps/dashboard/__init__.py | 4 + apps/dashboard/apps.py | 10 + apps/dashboard/urls.py | 12 ++ apps/dashboard/views/__init__.py | 0 apps/dashboard/views/index.py | 136 ++++++++++++ core/settings.py.example | 1 + core/urls.py | 1 + core/utils/mixins.py | 13 ++ templates/apps/accounts/user/profile.html | 8 + templates/apps/blog/page/detail.html | 3 +- templates/apps/blog/post/detail.html | 1 + templates/apps/dashboard/index.html | 248 ++++++++++++++++++++++ templates/includes/navbar.html | 2 +- 13 files changed, 437 insertions(+), 2 deletions(-) create mode 100644 apps/dashboard/__init__.py create mode 100644 apps/dashboard/apps.py create mode 100644 apps/dashboard/urls.py create mode 100644 apps/dashboard/views/__init__.py create mode 100644 apps/dashboard/views/index.py create mode 100644 core/utils/mixins.py create mode 100644 templates/apps/dashboard/index.html diff --git a/apps/dashboard/__init__.py b/apps/dashboard/__init__.py new file mode 100644 index 0000000..3f1a61d --- /dev/null +++ b/apps/dashboard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +default_app_config = 'apps.dashboard.apps.DashboardConfig' diff --git a/apps/dashboard/apps.py b/apps/dashboard/apps.py new file mode 100644 index 0000000..c441d7f --- /dev/null +++ b/apps/dashboard/apps.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.apps import AppConfig +from django.utils.translation import ugettext_lazy as _ + + +class DashboardConfig(AppConfig): + name = 'apps.dashboard' + verbose_name = _('App Dashboard') diff --git a/apps/dashboard/urls.py b/apps/dashboard/urls.py new file mode 100644 index 0000000..45cf3fa --- /dev/null +++ b/apps/dashboard/urls.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.urls import path + +from apps.dashboard.views.index import DashboardIndexView + +app_name = 'apps.dashboard' + +urlpatterns = [ + path('', DashboardIndexView.as_view(), name='dashboard_index'), +] diff --git a/apps/dashboard/views/__init__.py b/apps/dashboard/views/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/dashboard/views/index.py b/apps/dashboard/views/index.py new file mode 100644 index 0000000..e99e91a --- /dev/null +++ b/apps/dashboard/views/index.py @@ -0,0 +1,136 @@ +""" +Dashboard Index Views +to show all statistics. +""" +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.utils import timezone +from django.utils.translation import ugettext_lazy as _ +from django.views.generic import TemplateView + +from core.utils.mixins import SuperUserLoginRequiredMixin + +from apps.accounts.models.user import User +from apps.product.models.product import Product +from apps.blog.models.addons import Visitor +from apps.blog.models.post import Post +from apps.blog.models.tag import Tag + + +class DashboardIndexView(SuperUserLoginRequiredMixin, TemplateView): + template_name = 'apps/dashboard/index.html' + now = timezone.now() + + def get_total_tags(self, period: str, month: int = None) -> int: + """ + function to get the total tags per-month / year. + :param `period` is string period (choices: "year", "month") + :param `month` is optional integer month if it period as "month". + :return int total of tags. + """ + if period == 'year': + return Tag.objects.filter( + created_at__year=self.now.year + ).count() + elif period == 'month': + return Tag.objects.filter( + created_at__year=self.now.year, + created_at__month=month + ).count() + return 0 + + def get_total_users(self, period: str, month: int = None) -> int: + """ + function to get the total users per-month / year. + :param `period` is string period (choices: "year", "month") + :param `month` is optional integer month if it period as "month". + :return int total of users + """ + if period == 'year': + return User.objects.filter( + date_joined__year=self.now.year + ).count() + elif period == 'month': + return User.objects.filter( + date_joined__year=self.now.year, + date_joined__month=month + ).count() + return 0 + + def get_total_posts(self, period: str, month: int = None) -> int: + """ + function to get the total posts per-month / year. + :param `period` is string period (choices: "year", "month") + :param `month` is optional integer month if it period as "month". + :return int total of posts. + """ + if period == 'year': + return Post.objects.filter( + created_at__year=self.now.year + ).count() + elif period == 'month': + return Post.objects.filter( + created_at__year=self.now.year, + created_at__month=month + ).count() + return 0 + + def get_total_visitors(self, period: str, month: int = None) -> int: + """ + function to get the total visitors per-month / year. + :param `period` is string period (choices: "year", "month") + :param `month` is optional integer month if it period as "month". + :return int total of visitors. + """ + if period == 'year': + return Visitor.objects.filter( + created_at__year=self.now.year + ).count() + elif period == 'month': + return Visitor.objects.filter( + created_at__year=self.now.year, + created_at__month=month + ).count() + return 0 + + def get_data_visitors_per_months(self) -> list: + """ + function to get the calculate the total data + of visitors for each month. + :return list dict of data per month. + """ + data_per_months = [] + for month in range(1, 12): + total = self.get_total_visitors(period='month', month=month) + data_per_months.append(total) + return data_per_months + + def get_data_per_months(self) -> list: + """ + function to get the calculate the total data + includes (user, product) for each month. + :return list dict of data per month. + """ + data_per_months = [] + for month in range(1, 12): + data_per_months.append({ + 'tag': self.get_total_tags(period='month', month=month), + 'post': self.get_total_posts(period='month', month=month), + 'user': self.get_total_users(period='month', month=month) + }) + return data_per_months + + def get_context_data(self, **kwargs): + context_data = super().get_context_data(**kwargs) + context_data['total_tags'] = Tag.objects.all().count() + context_data['total_tags_this_year'] = self.get_total_tags(period='year') + context_data['total_users'] = User.objects.all().count() + context_data['total_users_this_year'] = self.get_total_users(period='year') + context_data['total_posts'] = Post.objects.all().count() + context_data['total_posts_this_year'] = self.get_total_posts(period='year') + context_data['total_visitors'] = Visitor.objects.all().count() + context_data['total_visitors_this_year'] = self.get_total_visitors(period='year') + context_data['data_visitors_per_months'] = self.get_data_visitors_per_months() + context_data['data_per_months'] = self.get_data_per_months() + return context_data diff --git a/core/settings.py.example b/core/settings.py.example index b83c594..9685221 100644 --- a/core/settings.py.example +++ b/core/settings.py.example @@ -89,6 +89,7 @@ INSTALLED_APPS = [ 'apps.blog', 'apps.product', 'apps.api', + 'apps.dashboard', ] diff --git a/core/urls.py b/core/urls.py index bf092ec..8ebe815 100644 --- a/core/urls.py +++ b/core/urls.py @@ -30,6 +30,7 @@ path('', include('apps.blog.urls')), path('', include('apps.product.urls')), path('api/', include('apps.api.urls')), + path('dash/', include('apps.dashboard.urls')), ] if settings.DEBUG: diff --git a/core/utils/mixins.py b/core/utils/mixins.py new file mode 100644 index 0000000..0babf90 --- /dev/null +++ b/core/utils/mixins.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.contrib.auth.mixins import LoginRequiredMixin + + +class SuperUserLoginRequiredMixin(LoginRequiredMixin): + + def dispatch(self, request, *args, **kwargs): + if request.user.is_authenticated: + if request.user.is_superuser: + return super().dispatch(request, *args, **kwargs) + return self.handle_no_permission() diff --git a/templates/apps/accounts/user/profile.html b/templates/apps/accounts/user/profile.html index 7d68a2f..07c3ddb 100644 --- a/templates/apps/accounts/user/profile.html +++ b/templates/apps/accounts/user/profile.html @@ -274,6 +274,14 @@
+ {{ user|get_total_posts|numberize }}
{{ tag_data.total }} + {% empty %} +
+ +
{% endfor %} diff --git a/templates/apps/blog/page/detail.html b/templates/apps/blog/page/detail.html index e126c0d..4d0070a 100644 --- a/templates/apps/blog/page/detail.html +++ b/templates/apps/blog/page/detail.html @@ -23,6 +23,7 @@ {% endblock %} {% block css %} + {% endblock %} @@ -30,7 +31,7 @@ {% block content %}
-
{{ page_title }}
+
{{ page_title }}
diff --git a/templates/apps/blog/post/detail.html b/templates/apps/blog/post/detail.html index dd59a5d..1cb2293 100644 --- a/templates/apps/blog/post/detail.html +++ b/templates/apps/blog/post/detail.html @@ -39,6 +39,7 @@ {% endblock %} {% block css %} + {% endblock %} diff --git a/templates/apps/dashboard/index.html b/templates/apps/dashboard/index.html new file mode 100644 index 0000000..2c9c4bf --- /dev/null +++ b/templates/apps/dashboard/index.html @@ -0,0 +1,248 @@ +{% extends "base.html" %} +{% load i18n static %} +{% load common_tags %} +{% block title %}{% trans "Dashboard" %} :: {{ block.super }}{% endblock %} + +{% block content %} +
+
+
+
+
+
+
+
+ + + + + +
+
+

{{ total_tags|numberize }}

+ {% trans "All tags created" %} +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
+

{{ total_posts|numberize }}

+ {% trans "All posts created" %} +
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+

{{ total_users|numberize }}

+ {% trans "All users registered" %} +
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+

{{ total_visitors|numberize }}

+ {% trans "All visitors visited" %} +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ + + + + +
+
+

{{ total_tags_this_year|numberize }}

+ {% trans "Tags this year" %} +
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
+

{{ total_posts_this_year|numberize }}

+ {% trans "Posts this year" %} +
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+

{{ total_users_this_year|numberize }}

+ {% trans "Users this year" %} +
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+

{{ total_visitors_this_year|numberize }}

+ {% trans "Visitors this year" %} +
+
+
+
+
+
+
+
+{% endblock %} + +{% block js %} + + +{% endblock %} diff --git a/templates/includes/navbar.html b/templates/includes/navbar.html index 97a4439..2b36f7d 100644 --- a/templates/includes/navbar.html +++ b/templates/includes/navbar.html @@ -127,7 +127,7 @@ {% trans "Your Products" %} {% if request.user.is_superuser %} - {% trans "Dashboard" %} + {% trans "Dashboard" %} {% endif %} {% trans "Settings" %} {% trans "Sign Out" %}