diff --git a/src/checkout/settings.py b/src/checkout/settings.py index 2c69411..c0a8a5a 100644 --- a/src/checkout/settings.py +++ b/src/checkout/settings.py @@ -15,6 +15,8 @@ from pathlib import Path import environ # Build paths inside the project like this: BASE_DIR / 'subdir'. +from django.contrib import messages + BASE_DIR = Path(__file__).resolve(strict=True).parent.parent env = environ.Env( @@ -196,7 +198,7 @@ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") # CSP CSP_DEFAULT_SRC = ("'none'",) -CSP_IMG_SRC = ("'self'",) +CSP_IMG_SRC = ("'self'", "data:") CSP_SCRIPT_SRC = ("'self'", "'unsafe-inline'") CSP_CONNECT_SRC = ("'self'",) CSP_STYLE_SRC = ("'self'", "'unsafe-inline'") @@ -209,3 +211,5 @@ DEFAULT_AUTO_FIELD = "django.db.models.AutoField" CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5" CRISPY_TEMPLATE_PACK = "bootstrap5" + +MESSAGE_TAGS = {messages.ERROR: "danger"} diff --git a/src/common/templates/common/base.html b/src/common/templates/common/base.html index 9bf4f01..624d66d 100644 --- a/src/common/templates/common/base.html +++ b/src/common/templates/common/base.html @@ -3,6 +3,7 @@ + Checkout @@ -12,6 +13,7 @@
{% include "common/navbar.html" %} + {% include "common/messages.html" %} {% block content %} {% endblock %}
diff --git a/src/common/templates/common/messages.html b/src/common/templates/common/messages.html new file mode 100644 index 0000000..a660a60 --- /dev/null +++ b/src/common/templates/common/messages.html @@ -0,0 +1,10 @@ +{% if messages %} +
+ {% for message in messages %} + + {% endfor %} +
+{% endif %} diff --git a/src/purchase/views.py b/src/purchase/views.py index d54745f..ac0b8c4 100644 --- a/src/purchase/views.py +++ b/src/purchase/views.py @@ -1,4 +1,5 @@ from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin +from django.contrib.messages.views import SuccessMessageMixin from django.urls import reverse from django.views.generic import CreateView, DeleteView, ListView, UpdateView @@ -10,16 +11,18 @@ class ProtectedViewsMixin(PermissionRequiredMixin, LoginRequiredMixin): pass -class NewBasketView(ProtectedViewsMixin, CreateView): +class NewBasketView(ProtectedViewsMixin, SuccessMessageMixin, CreateView): permission_required = ["purchase.add_basket"] model = Basket form_class = BasketForm + success_message = "Successfully created basket." -class UpdateBasketView(ProtectedViewsMixin, UpdateView): +class UpdateBasketView(ProtectedViewsMixin, SuccessMessageMixin, UpdateView): permission_required = ["purchase.change_basket", "purchase.view_basket"] model = Basket form_class = BasketForm + success_message = "Successfully updated basket." class ListBasketsView(ProtectedViewsMixin, ListView): @@ -29,9 +32,10 @@ class ListBasketsView(ProtectedViewsMixin, ListView): ordering = "-id" -class DeleteBasketView(ProtectedViewsMixin, DeleteView): +class DeleteBasketView(ProtectedViewsMixin, SuccessMessageMixin, DeleteView): permission_required = ["purchase.delete_basket"] model = Basket + success_message = "Basket successfully deleted." def get_success_url(self): return reverse("purchase:list")