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 %}{% 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 %}
+{% endfor %}
+{% if initial %}
+ {{ initial }}
+{% endif %}
{{ component }}>
\ 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