Create a generic form fragment renderer

This commit is contained in:
Antoine Bartuccio 2024-12-08 11:45:16 +01:00
parent 66d2dc74e7
commit de7aa6f6a6
7 changed files with 150 additions and 158 deletions

View File

@ -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 %}
{{ student_card }}
<p class="justify">
{% 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 %}
</p>
{% endif %}
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -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.

View File

@ -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

View File

@ -31,18 +31,11 @@
<p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p>
{% 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 %}
</div>
{{ student_card }}
{% endif %}
</div>
<div id="click_form">
<div id="click_form">
<h5>{% trans %}Selling{% endtrans %}</h5>
<div>
{% set counter_click_url = url('counter:click', counter_id=counter.id, user_id=customer.user_id) %}
@ -123,9 +116,9 @@
</form>
</div>
{% endif %}
</div>
</div>
<div id="products">
<div id="products">
<ul>
{% for category in categories.keys() -%}
<li><a href="#cat_{{ category|slugify }}">{{ category }}</a></li>
@ -154,8 +147,8 @@
{%- endfor %}
</div>
{%- endfor %}
</div>
</div>
</div>
</div>
{% endblock content %}
{% block script %}

View File

@ -7,7 +7,7 @@
>
{% csrf_token %}
{{ form.as_p() }}
<button>{% trans %}Go{% endtrans %}</button>
<input type="submit" value="{% trans %}Go{% endtrans %}"/>
</form>
<h6>{% trans %}Registered cards{% endtrans %}</h6>

View File

@ -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

View File

@ -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