diff --git a/accounting/widgets/select.py b/accounting/widgets/select.py index a27a6c6a..27714440 100644 --- a/accounting/widgets/select.py +++ b/accounting/widgets/select.py @@ -1,3 +1,5 @@ +from pydantic import TypeAdapter + from accounting.models import ClubAccount, Company from accounting.schemas import ClubAccountSchema, CompanySchema from core.views.widgets.select import AutoCompleteSelect, AutoCompleteSelectMultiple @@ -8,7 +10,7 @@ _js = ["webpack/accounting/components/ajax-select-index.ts"] class AutoCompleteSelectClubAccount(AutoCompleteSelect): component_name = "club-account-ajax-select" model = ClubAccount - schema = ClubAccountSchema + adapter = TypeAdapter(list[ClubAccountSchema]) js = _js @@ -16,7 +18,7 @@ class AutoCompleteSelectClubAccount(AutoCompleteSelect): class AutoCompleteSelectMultipleClubAccount(AutoCompleteSelectMultiple): component_name = "club-account-ajax-select" model = ClubAccount - schema = ClubAccountSchema + adapter = TypeAdapter(list[ClubAccountSchema]) js = _js @@ -24,7 +26,7 @@ class AutoCompleteSelectMultipleClubAccount(AutoCompleteSelectMultiple): class AutoCompleteSelectCompany(AutoCompleteSelect): component_name = "company-ajax-select" model = Company - schema = CompanySchema + adapter = TypeAdapter(list[CompanySchema]) js = _js @@ -32,6 +34,6 @@ class AutoCompleteSelectCompany(AutoCompleteSelect): class AutoCompleteSelectMultipleCompany(AutoCompleteSelectMultiple): component_name = "company-ajax-select" model = Company - schema = CompanySchema + adapter = TypeAdapter(list[CompanySchema]) js = _js diff --git a/club/widgets/select.py b/club/widgets/select.py index 87184ed2..c7063328 100644 --- a/club/widgets/select.py +++ b/club/widgets/select.py @@ -1,3 +1,5 @@ +from pydantic import TypeAdapter + from club.models import Club from club.schemas import ClubSchema from core.views.widgets.select import AutoCompleteSelect, AutoCompleteSelectMultiple @@ -8,7 +10,7 @@ _js = ["webpack/club/components/ajax-select-index.ts"] class AutoCompleteSelectClub(AutoCompleteSelect): component_name = "club-ajax-select" model = Club - schema = ClubSchema + adapter = TypeAdapter(list[ClubSchema]) js = _js @@ -16,6 +18,6 @@ class AutoCompleteSelectClub(AutoCompleteSelect): class AutoCompleteSelectMultipleClub(AutoCompleteSelectMultiple): component_name = "club-ajax-select" model = Club - schema = ClubSchema + adapter = TypeAdapter(list[ClubSchema]) js = _js diff --git a/core/templates/core/widgets/autocomplete_select.jinja b/core/templates/core/widgets/autocomplete_select.jinja index 1858cccd..12d1d254 100644 --- a/core/templates/core/widgets/autocomplete_select.jinja +++ b/core/templates/core/widgets/autocomplete_select.jinja @@ -5,9 +5,19 @@ {% endfor %} -<{{ component }} name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>{% for group_name, group_choices, group_index in widget.optgroups %}{% if group_name %} - {% endif %}{% for widget in group_choices %} - {% include widget.template_name %}{% endfor %}{% if group_name %} - {% endif %}{% endfor %} -{% if initial %}{{ initial }}{% endif %} +<{{ component }} name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}> +{% for group_name, group_choices, group_index in widget.optgroups %} + {% if group_name %} + + {% endif %} + {% for widget in group_choices %} + {% include widget.template_name %} + {% endfor %} + {% if group_name %} + + {% endif %} +{% endfor %} +{% if initial %} + {{ initial }} +{% endif %} \ No newline at end of file diff --git a/core/views/widgets/select.py b/core/views/widgets/select.py index bc5b2711..a7f600be 100644 --- a/core/views/widgets/select.py +++ b/core/views/widgets/select.py @@ -1,5 +1,8 @@ +from collections.abc import Collection +from typing import Any + from django.contrib.staticfiles.storage import staticfiles_storage -from django.db.models import Model +from django.db.models import Model, QuerySet from django.forms import Select, SelectMultiple from ninja import ModelSchema from pydantic import TypeAdapter @@ -11,8 +14,8 @@ from core.schemas import GroupSchema, SithFileSchema, UserProfileSchema class AutoCompleteSelectMixin: component_name = "autocomplete-select" template_name = "core/widgets/autocomplete_select.jinja" - model: Model | None = None - schema: ModelSchema | None = None + model: type[Model] | None = None + adapter: TypeAdapter[Collection[ModelSchema]] | None = None pk = "id" js = [ @@ -23,6 +26,17 @@ class AutoCompleteSelectMixin: "core/components/ajax-select.scss", ] + def get_queryset(self, pks: Collection[Any]) -> QuerySet: + return self.model.objects.filter( + **{ + f"{self.pk}__in": [ + pk + for pk in pks + if str(pk).isdigit() # We filter empty values for create views + ] + } + ).all() + def __init__(self, attrs=None, choices=()): if self.is_ajax: choices = () # Avoid computing anything when in ajax mode @@ -30,7 +44,7 @@ class AutoCompleteSelectMixin: @property def is_ajax(self): - return self.model and self.schema + return self.adapter and self.model def optgroups(self, name, value, attrs=None): """Don't create option groups when doing ajax""" @@ -47,20 +61,9 @@ class AutoCompleteSelectMixin: "css": [staticfiles_storage.url(file) for file in self.css], } if self.is_ajax: - adapter = TypeAdapter(list[self.schema]) - context["initial"] = adapter.dump_json( - adapter.validate_python( - self.model.objects.filter( - **{ - f"{self.pk}__in": [ - pk - for pk in context["widget"]["value"] - if str( - pk - ).isdigit() # We filter empty values for create views - ] - } - ).all() + context["initial"] = self.adapter.dump_json( + self.adapter.validate_python( + self.get_queryset(context["widget"]["value"]) ) ).decode("utf-8") return context @@ -75,34 +78,34 @@ class AutoCompleteSelectMultiple(AutoCompleteSelectMixin, SelectMultiple): ... class AutoCompleteSelectUser(AutoCompleteSelect): component_name = "user-ajax-select" model = User - schema = UserProfileSchema + adapter = TypeAdapter(list[UserProfileSchema]) class AutoCompleteSelectMultipleUser(AutoCompleteSelectMultiple): component_name = "user-ajax-select" model = User - schema = UserProfileSchema + adapter = TypeAdapter(list[UserProfileSchema]) class AutoCompleteSelectGroup(AutoCompleteSelect): component_name = "group-ajax-select" model = Group - schema = GroupSchema + adapter = TypeAdapter(list[GroupSchema]) class AutoCompleteSelectMultipleGroup(AutoCompleteSelectMultiple): component_name = "group-ajax-select" model = Group - schema = GroupSchema + adapter = TypeAdapter(list[GroupSchema]) class AutoCompleteSelectSithFile(AutoCompleteSelect): component_name = "sith-file-ajax-select" model = SithFile - schema = SithFileSchema + adapter = TypeAdapter(list[SithFileSchema]) class AutoCompleteSelectMultipleSithFile(AutoCompleteSelectMultiple): component_name = "sith-file-ajax-select" model = SithFile - schema = SithFileSchema + adapter = TypeAdapter(list[SithFileSchema]) diff --git a/counter/widgets/select.py b/counter/widgets/select.py index e076de63..53c0bc9f 100644 --- a/counter/widgets/select.py +++ b/counter/widgets/select.py @@ -1,3 +1,5 @@ +from pydantic import TypeAdapter + from core.views.widgets.select import AutoCompleteSelect, AutoCompleteSelectMultiple from counter.models import Counter, Product from counter.schemas import ProductSchema, SimplifiedCounterSchema @@ -8,26 +10,26 @@ _js = ["webpack/counter/components/ajax-select-index.ts"] class AutoCompleteSelectCounter(AutoCompleteSelect): component_name = "counter-ajax-select" model = Counter - schema = SimplifiedCounterSchema + adapter = TypeAdapter(list[SimplifiedCounterSchema]) js = _js class AutoCompleteSelectMultipleCounter(AutoCompleteSelectMultiple): component_name = "counter-ajax-select" model = Counter - schema = SimplifiedCounterSchema + adapter = TypeAdapter(list[SimplifiedCounterSchema]) js = _js class AutoCompleteSelectProduct(AutoCompleteSelect): component_name = "product-ajax-select" model = Product - schema = ProductSchema + adapter = TypeAdapter(list[ProductSchema]) js = _js class AutoCompleteSelectMultipleProduct(AutoCompleteSelectMultiple): component_name = "product-ajax-select" model = Product - schema = ProductSchema + adapter = TypeAdapter(list[ProductSchema]) js = _js diff --git a/sas/widgets/select.py b/sas/widgets/select.py index c737c747..be5c3ebb 100644 --- a/sas/widgets/select.py +++ b/sas/widgets/select.py @@ -1,3 +1,5 @@ +from pydantic import TypeAdapter + from core.views.widgets.select import ( AutoCompleteSelect, AutoCompleteSelectMultiple, @@ -11,7 +13,7 @@ _js = ["webpack/sas/components/ajax-select-index.ts"] class AutoCompleteSelectAlbum(AutoCompleteSelect): component_name = "album-ajax-select" model = Album - schema = AlbumSchema + adapter = TypeAdapter(list[AlbumSchema]) js = _js @@ -19,6 +21,6 @@ class AutoCompleteSelectAlbum(AutoCompleteSelect): class AutoCompleteSelectMultipleAlbum(AutoCompleteSelectMultiple): component_name = "album-ajax-select" model = Album - schema = AlbumSchema + adapter = TypeAdapter(list[AlbumSchema]) js = _js