From de7aa6f6a6e08bd790ca59a3e3461924f47eda17 Mon Sep 17 00:00:00 2001 From: Sli Date: Sun, 8 Dec 2024 11:45:16 +0100 Subject: [PATCH] Create a generic form fragment renderer --- core/templates/core/user_preferences.jinja | 22 +- core/utils.py | 25 +- core/views/user.py | 4 +- counter/templates/counter/counter_click.jinja | 229 +++++++++--------- .../fragments/create_student_card.jinja | 2 +- counter/views/click.py | 4 +- counter/views/student_card.py | 22 +- 7 files changed, 150 insertions(+), 158 deletions(-) diff --git a/core/templates/core/user_preferences.jinja b/core/templates/core/user_preferences.jinja index d70371a2..722e7c44 100644 --- a/core/templates/core/user_preferences.jinja +++ b/core/templates/core/user_preferences.jinja @@ -36,19 +36,11 @@ {% if student_card %} - {% with - form=student_card.form, - action=student_card.context.action, - customer=student_card.context.customer, - student_cards=student_card.context.student_cards - %} - {% include student_card.template %} - {% endwith %} - -

- {% trans %}You can add a card by asking at a counter or add it yourself here. If you want to manually - add a student card yourself, you'll need a NFC reader. We store the UID of the card which is 14 characters long.{% endtrans %} -

-{% endif %} - + {{ student_card }} +

+ {% trans %}You can add a card by asking at a counter or add it yourself here. If you want to manually + add a student card yourself, you'll need a NFC reader. We store the UID of the card which is 14 characters long.{% endtrans %} +

+ {% endif %} + {% endblock %} \ No newline at end of file diff --git a/core/utils.py b/core/utils.py index 5b6191f6..cdd72fa6 100644 --- a/core/utils.py +++ b/core/utils.py @@ -13,22 +13,41 @@ # # +from dataclasses import dataclass from datetime import date # Image utils from io import BytesIO -from typing import Optional +from typing import Any import PIL from django.conf import settings from django.core.files.base import ContentFile +from django.forms import BaseForm from django.http import HttpRequest +from django.template.loader import render_to_string +from django.utils.html import SafeString from django.utils.timezone import localdate from PIL import ExifTags from PIL.Image import Image, Resampling -def get_start_of_semester(today: Optional[date] = None) -> date: +@dataclass +class FormFragmentTemplateData[T: BaseForm]: + """Dataclass used to pre-render form fragments""" + + form: T + template: str + context: dict[str, Any] + + def render(self, request: HttpRequest) -> SafeString: + # Request is needed for csrf_tokens + return render_to_string( + self.template, context={"form": self.form, **self.context}, request=request + ) + + +def get_start_of_semester(today: date | None = None) -> date: """Return the date of the start of the semester of the given date. If no date is given, return the start date of the current semester. @@ -58,7 +77,7 @@ def get_start_of_semester(today: Optional[date] = None) -> date: return autumn.replace(year=autumn.year - 1) -def get_semester_code(d: Optional[date] = None) -> str: +def get_semester_code(d: date | None = None) -> str: """Return the semester code of the given date. If no date is given, return the semester code of the current semester. diff --git a/core/views/user.py b/core/views/user.py index 83916fb1..2c6b01fc 100644 --- a/core/views/user.py +++ b/core/views/user.py @@ -578,8 +578,8 @@ class UserPreferencesView(UserTabsMixin, CanEditMixin, UpdateView): kwargs["trombi_form"] = UserTrombiForm() if hasattr(self.object, "customer"): kwargs["student_card"] = StudentCardFormView.get_template_data( - self.request, self.object.customer - ).as_dict() + self.object.customer + ).render(self.request) return kwargs diff --git a/counter/templates/counter/counter_click.jinja b/counter/templates/counter/counter_click.jinja index ed89b100..7c36b01b 100644 --- a/counter/templates/counter/counter_click.jinja +++ b/counter/templates/counter/counter_click.jinja @@ -31,131 +31,124 @@

{% trans %}Amount: {% endtrans %}{{ customer.amount }} €

{% if counter.type == 'BAR' %} - {% with - form=student_card.form, - action=student_card.context.action, - customer=student_card.context.customer, - student_cards=student_card.context.student_cards - %} - {% include student_card.template %} - {% endwith %} -{% endif %} - + {{ student_card }} + {% endif %} + -
-
{% trans %}Selling{% endtrans %}
-
- {% set counter_click_url = url('counter:click', counter_id=counter.id, user_id=customer.user_id) %} +
+
{% trans %}Selling{% endtrans %}
+
+ {% set counter_click_url = url('counter:click', counter_id=counter.id, user_id=customer.user_id) %} {# Formulaire pour rechercher un produit en tapant son code dans une barre de recherche #} -
- {% csrf_token %} - - - - -
- - -

{% trans %}Basket: {% endtrans %}

- -
    - -
-

- Total: - - -

- -
- {% csrf_token %} - - -
-
- {% csrf_token %} - - -
-
- {% if (counter.type == 'BAR' and barmens_can_refill) %} -
{% trans %}Refilling{% endtrans %}
-
-
- {% csrf_token %} - {{ refill_form.as_p() }} - - -
-
- {% endif %} -
- -
-
    - {% for category in categories.keys() -%} -
  • {{ category }}
  • - {%- endfor %} -
- {% for category in categories.keys() -%} -
-
{{ category }}
- {% for p in categories[category] -%} -
+ {% csrf_token %} - - - + + + +
+ + +

{% trans %}Basket: {% endtrans %}

+ +
    + +
+

+ Total: + + +

+ +
+ {% csrf_token %} + + +
+
+ {% csrf_token %} + + +
+
+ {% if (counter.type == 'BAR' and barmens_can_refill) %} +
{% trans %}Refilling{% endtrans %}
+
+
+ {% csrf_token %} + {{ refill_form.as_p() }} + + +
+
+ {% endif %} +
+ +
+
    + {% for category in categories.keys() -%} +
  • {{ category }}
  • + {%- endfor %} +
+ {% for category in categories.keys() -%} +
+
{{ category }}
+ {% for p in categories[category] -%} +
+ {% csrf_token %} + + + +
+ {%- endfor %} +
{%- endfor %}
- {%- endfor %} -
-
+ {% endblock content %} {% block script %} diff --git a/counter/templates/counter/fragments/create_student_card.jinja b/counter/templates/counter/fragments/create_student_card.jinja index 7cd05ba9..ab846c55 100644 --- a/counter/templates/counter/fragments/create_student_card.jinja +++ b/counter/templates/counter/fragments/create_student_card.jinja @@ -7,7 +7,7 @@ > {% csrf_token %} {{ form.as_p() }} - +
{% trans %}Registered cards{% endtrans %}
diff --git a/counter/views/click.py b/counter/views/click.py index c0845aaf..2fa9684d 100644 --- a/counter/views/click.py +++ b/counter/views/click.py @@ -416,6 +416,6 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView): kwargs["refill_form"] = self.refill_form or RefillForm() kwargs["barmens_can_refill"] = self.object.can_refill() kwargs["student_card"] = StudentCardFormView.get_template_data( - self.request, self.customer - ).as_dict() + self.customer + ).render(self.request) return kwargs diff --git a/counter/views/student_card.py b/counter/views/student_card.py index fb919ce2..99f67316 100644 --- a/counter/views/student_card.py +++ b/counter/views/student_card.py @@ -14,31 +14,19 @@ # -from dataclasses import asdict, dataclass -from typing import Any - from django.core.exceptions import PermissionDenied from django.http import HttpRequest from django.shortcuts import get_object_or_404 from django.urls import reverse_lazy from django.views.generic.edit import DeleteView, FormView +from core.utils import FormFragmentTemplateData from core.views import CanEditMixin from counter.forms import StudentCardForm from counter.models import Customer, StudentCard from counter.utils import is_logged_in_counter -@dataclass -class StudentCardTemplateData: - form: StudentCardForm - template: str - context: dict[str, Any] - - def as_dict(self) -> dict[str, Any]: - return asdict(self) - - class StudentCardDeleteView(DeleteView, CanEditMixin): """View used to delete a card from a user.""" @@ -64,10 +52,10 @@ class StudentCardFormView(FormView): @classmethod def get_template_data( - cls, request: HttpRequest, customer: Customer - ) -> StudentCardTemplateData: + cls, customer: Customer + ) -> FormFragmentTemplateData[form_class]: """Get necessary data to pre-render the fragment""" - return StudentCardTemplateData( + return FormFragmentTemplateData[cls.form_class]( form=cls.form_class(), template=cls.template_name, context={ @@ -99,7 +87,7 @@ class StudentCardFormView(FormView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - data = self.get_template_data(self.request, self.customer) + data = self.get_template_data(self.customer) context.update(data.context) return context