mirror of
https://github.com/Crocmagnon/checkout.git
synced 2024-12-22 14:11:48 +01:00
Load graphs asynchronously
This commit is contained in:
parent
68ba920882
commit
ae5860fc17
11 changed files with 66 additions and 20 deletions
14
poetry.lock
generated
14
poetry.lock
generated
|
@ -342,6 +342,17 @@ python-versions = ">=3.6"
|
|||
[package.dependencies]
|
||||
Django = ">=3.2"
|
||||
|
||||
[[package]]
|
||||
name = "django-htmx"
|
||||
version = "1.12.2"
|
||||
description = "Extensions for using Django with htmx."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
Django = ">=3.2"
|
||||
|
||||
[[package]]
|
||||
name = "factory-boy"
|
||||
version = "3.2.1"
|
||||
|
@ -1153,7 +1164,7 @@ h11 = ">=0.9.0,<1"
|
|||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "e21ae8f93aefc631a43ccf43b79a3660ca11c6870677d60878b0adc88303953d"
|
||||
content-hash = "e0332f1446a90fc3a5dc2fa2ca5d1745eb0d90d8f033094d79b2df9376b79639"
|
||||
|
||||
[metadata.files]
|
||||
ansicon = []
|
||||
|
@ -1276,6 +1287,7 @@ django-environ = [
|
|||
{file = "django_environ-0.9.0-py2.py3-none-any.whl", hash = "sha256:f21a5ef8cc603da1870bbf9a09b7e5577ab5f6da451b843dbcc721a7bca6b3d9"},
|
||||
]
|
||||
django-extensions = []
|
||||
django-htmx = []
|
||||
factory-boy = []
|
||||
faker = []
|
||||
filelock = []
|
||||
|
|
|
@ -21,6 +21,7 @@ django-crispy-forms = "^1.14.0"
|
|||
crispy-bootstrap5 = "^0.6"
|
||||
matplotlib = "^3.5.1"
|
||||
freezegun = "^1.2.1"
|
||||
django-htmx = "^1.12.2"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pre-commit = "^2.7"
|
||||
|
|
|
@ -89,6 +89,7 @@ INSTALLED_APPS = [
|
|||
"crispy_forms",
|
||||
"crispy_bootstrap5",
|
||||
"django_extensions",
|
||||
"django_htmx",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -102,6 +103,7 @@ MIDDLEWARE = [
|
|||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
"csp.middleware.CSPMiddleware",
|
||||
"django_htmx.middleware.HtmxMiddleware",
|
||||
]
|
||||
|
||||
try:
|
||||
|
|
1
src/common/static/vendor/htmx-1.8.0/htmx.min.js
vendored
Normal file
1
src/common/static/vendor/htmx-1.8.0/htmx.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -28,5 +28,7 @@
|
|||
{% endblock %}
|
||||
</div>
|
||||
<script src="{% static "vendor/bootstrap-5.1.3-dist/js/bootstrap.bundle.min.js" %}"></script>
|
||||
{% block extrascript %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
BIN
src/purchase/static/purchase/spinner.gif
Normal file
BIN
src/purchase/static/purchase/spinner.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
|
@ -1,7 +1,5 @@
|
|||
{% extends "common/base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load purchase %}
|
||||
{% load static i18n purchase django_htmx %}
|
||||
|
||||
{% block extrahead %}
|
||||
<link rel="stylesheet" href="{% static "purchase/css/reports.css" %}">
|
||||
|
@ -29,18 +27,20 @@
|
|||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{{ by_hour_plot|safe }}
|
||||
{% include "purchase/snippets/htmx_plot.html" with url='purchase:by_hour_plot' %}
|
||||
|
||||
<h2>{% translate "Products" %}</h2>
|
||||
{% include "purchase/snippets/report_products.html" %}
|
||||
{{ products_plot|safe }}
|
||||
{{ products_sold_pie|safe }}
|
||||
{{ products_turnover_pie|safe }}
|
||||
{% include "purchase/snippets/htmx_plot.html" with url='purchase:products_plots' %}
|
||||
|
||||
<h2>{% translate "Turnover by payment method" %}</h2>
|
||||
{% include "purchase/snippets/report_payment_methods.html" %}
|
||||
|
||||
<h2>{% translate "Baskets without payment method" %}</h2>
|
||||
{% include "purchase/snippets/report_no_payment_method.html" %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block extrascript %}
|
||||
<script src="{% static 'vendor/htmx-1.8.0/htmx.min.js' %}" defer></script>
|
||||
{% django_htmx_script %}
|
||||
{% endblock %}
|
||||
|
|
7
src/purchase/templates/purchase/snippets/htmx_plot.html
Normal file
7
src/purchase/templates/purchase/snippets/htmx_plot.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
{% load static %}
|
||||
<div hx-get="{% url url %}"
|
||||
hx-trigger="load"
|
||||
hx-swap="outerHTML"
|
||||
>
|
||||
<img class="htmx-indicator" src="{% static 'purchase/spinner.gif' %}" alt="Spinner">
|
||||
</div>
|
3
src/purchase/templates/purchase/snippets/plots.html
Normal file
3
src/purchase/templates/purchase/snippets/plots.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
{% for plot in plots %}
|
||||
{{ plot|safe }}
|
||||
{% endfor %}
|
|
@ -1,7 +1,7 @@
|
|||
from django.urls import path
|
||||
|
||||
from purchase.views import delete_basket, list_baskets, new_basket, update_basket
|
||||
from purchase.views.reports import reports
|
||||
from purchase.views.reports import by_hour_plot_view, products_plots_view, reports
|
||||
|
||||
app_name = "purchase"
|
||||
urlpatterns = [
|
||||
|
@ -10,4 +10,7 @@ urlpatterns = [
|
|||
path("<int:pk>/update/", update_basket, name="update"),
|
||||
path("<int:pk>/delete/", delete_basket, name="delete"),
|
||||
path("reports/", reports, name="reports"),
|
||||
# plots
|
||||
path("reports/products_plots/", products_plots_view, name="products_plots"),
|
||||
path("reports/by_hour_plot/", by_hour_plot_view, name="by_hour_plot"),
|
||||
]
|
||||
|
|
|
@ -7,6 +7,7 @@ import numpy as np
|
|||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
from django.shortcuts import render
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.translation import gettext as _
|
||||
from matplotlib import pyplot as plt
|
||||
|
@ -18,7 +19,30 @@ from matplotlib.figure import Figure
|
|||
|
||||
from purchase.models import Basket, PaymentMethod, Product, ProductQuerySet
|
||||
|
||||
matplotlib.use("TkAgg")
|
||||
matplotlib.use("Agg")
|
||||
|
||||
|
||||
@permission_required("purchase.view_basket")
|
||||
def products_plots_view(request):
|
||||
products = Product.objects.with_turnover().with_sold()
|
||||
(
|
||||
products_plot,
|
||||
products_sold_pie,
|
||||
products_turnover_pie,
|
||||
) = get_products_plots(products)
|
||||
context = {
|
||||
"plots": [products_plot, products_sold_pie, products_turnover_pie],
|
||||
}
|
||||
return render(request, "purchase/snippets/plots.html", context)
|
||||
|
||||
|
||||
@permission_required("purchase.view_basket")
|
||||
def by_hour_plot_view(request):
|
||||
baskets = list(Basket.objects.priced().order_by("created_at"))
|
||||
context = {
|
||||
"plots": [by_hour_plot(baskets)],
|
||||
}
|
||||
return render(request, "purchase/snippets/plots.html", context)
|
||||
|
||||
|
||||
@permission_required("purchase.view_basket")
|
||||
|
@ -36,11 +60,6 @@ def reports(request):
|
|||
turnover_by_day = {date: Basket.objects.by_date(date).turnover() for date in dates}
|
||||
|
||||
products = Product.objects.with_turnover().with_sold()
|
||||
(
|
||||
products_plot,
|
||||
products_sold_pie,
|
||||
products_turnover_pie,
|
||||
) = get_products_plots(products)
|
||||
|
||||
context = {
|
||||
"turnover": Basket.objects.turnover(),
|
||||
|
@ -48,10 +67,6 @@ def reports(request):
|
|||
"average_basket": Basket.objects.average_basket(),
|
||||
"average_basket_by_day": average_basket_by_day,
|
||||
"products": products,
|
||||
"products_plot": products_plot,
|
||||
"products_sold_pie": products_sold_pie,
|
||||
"products_turnover_pie": products_turnover_pie,
|
||||
"by_hour_plot": by_hour_plot(baskets),
|
||||
"payment_methods": PaymentMethod.objects.with_turnover().with_sold(),
|
||||
"no_payment_method": Basket.objects.no_payment_method().priced(),
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue