Frontend Comparison: alight vs select2¶
Both frontends share the same Django-side base classes
(BaseQuerySetView, ViewMixin, forward.py).
They differ in what the view returns and which JS component renders it.
Core difference¶
Aspect |
|
|
|---|---|---|
Response format |
HTML fragments |
JSON |
JS payload |
|
Select2 4.x (~170 KB) + jQuery (via Django admin) + 5 KB DAL glue |
Browser API |
Native Custom Elements v1, no framework |
jQuery plugin, |
Feature matrix¶
Feature |
alight |
select2 |
Notes |
|---|---|---|---|
Single FK |
yes |
yes |
|
Multiple M2M |
yes |
yes |
|
Free list |
yes |
yes |
|
Tags / comma-separated |
yes |
yes |
|
django-taggit integration |
yes |
yes |
|
Grouped results |
yes |
yes |
|
Grouped free list |
yes |
yes |
|
Generic FK via queryset-sequence |
yes |
yes |
|
Create on the fly |
yes |
yes |
alight: |
Infinite scroll / pagination |
yes |
yes |
alight: |
Field forwarding |
yes |
yes |
Both use the same |
Django admin popup sync |
yes |
yes |
alight patches |
Minimum input length |
yes |
yes |
alight: |
Clear / remove selection |
yes |
yes |
alight uses × buttons in the deck |
Client-side local filtering |
yes |
no |
alight: |
Max-choices cap with auto-eviction |
yes |
no |
alight: |
i18n of widget UI strings |
planned |
yes |
alight UI strings can be overridden via custom attributes or Django’s i18n machinery; select2 ships 59 locale files |
Distinct selected-item label |
no |
yes |
alight deck always shows the same label as the dropdown; select2:
|
Token separators for tags |
no |
yes |
alight requires click or Enter; select2: |
Rich HTML result/selection templates |
partial |
yes |
alight renders |
When to use dal_alight¶
No jQuery in the stack (modern frontend, HTMX, API-only server-side, etc.).
Minimising JS payload and eliminating third-party dependencies is a priority.
You want
max-choicesenforcement client-side without extra code.Some fields use a small static choice list and local filtering avoids an unnecessary server round-trip.
You prefer the server to own result rendering (HTML fragments) rather than templating in JS — useful when labels contain Django template logic or server-side permissions.
You are building a web-component or shadow-DOM ecosystem and need a widget that fits naturally as a Custom Element.
Known gaps in dal_alight¶
Note
These are deliberate trade-offs or deferred features, not bugs.
i18n — the three user-visible strings (“Search…”, “No result”, “Create …”) can be overridden via custom HTML attributes on the widget, or rendered server-side through Django’s i18n machinery.
No
selected_text— there is no mechanism to show a different label once an item is selected. The deck always showsget_result_label(). Select2’sget_selected_result_label()hook has no alight equivalent yet.No token separators — in tag mode the user must click or press Enter to commit a tag; typing a separator character does not auto-commit.
When to use dal_select2¶
Use dal_select2 when you require one of these specific features not yet in
dal_alight:
A distinct label in the “selected chip” versus the dropdown item (
get_selected_result_label).Token separators for tag creation (typing
,to commit a tag without clicking).Results with rich HTML requiring different rendering for dropdown vs selection display.
Browsers or CSP policies that disallow Custom Elements.
Class name mapping¶
|
|
Kind |
|---|---|---|
View |
||
View |
||
View |
||
View |
||
View (GFK) |
||
Widget — FK |
||
Widget — M2M |
||
Widget — arbitrary choices, single |
||
Widget — arbitrary choices, multiple |
||
Widget — list-backed |
||
Widget — free-text tags |
||
Widget — django-taggit |
||
Widget — GFK single |
||
Widget — GFK multiple |
||
Form field |
||
Form field |
||
Form field — GFK auto-view |