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

dal_alight

dal_select2

Response format

HTML fragments <div data-value="pk">Label</div>

JSON {results:[{id, text, selected_text}], pagination:{more}}

JS payload

autocomplete-light web component (15 KB) + 11 KB DAL adapter. No jQuery.

Select2 4.x (~170 KB) + jQuery (via Django admin) + 5 KB DAL glue

Browser API

Native Custom Elements v1, no framework

jQuery plugin, data-* attribute wiring

Feature matrix

Feature

alight

select2

Notes

Single FK

yes

yes

ModelAlight / ModelSelect2

Multiple M2M

yes

yes

ModelAlightMultiple / ModelSelect2Multiple

Free list

yes

yes

ListAlight + corresponding views / ListSelect2

Tags / comma-separated

yes

yes

TagAlight / TagSelect2

django-taggit integration

yes

yes

TaggitAlight / TaggitSelect2

Grouped results

yes

yes

AlightGroupQuerySetView / Select2GroupQuerySetView

Grouped free list

yes

yes

AlightGroupListView / Select2GroupListView

Generic FK via queryset-sequence

yes

yes

dal_alight_queryset_sequence / dal_select2_queryset_sequence

Create on the fly

yes

yes

alight: <div data-create> sentinel; select2: JSON flag create_id:true

Infinite scroll / pagination

yes

yes

alight: <div data-next-page> sentinel; select2: pagination.more

Field forwarding

yes

yes

Both use the same forward.py; alight adapter is vanilla JS

Django admin popup sync

yes

yes

alight patches dismissAddRelatedObjectPopup in dal-django.js

Minimum input length

yes

yes

alight: minimum-characters attribute; select2: data-minimum-input-length

Clear / remove selection

yes

yes

alight uses × buttons in the deck

Client-side local filtering

yes

no

alight: Alight / AlightMultiple without a url filter <option> elements locally — no server round-trip

Max-choices cap with auto-eviction

yes

no

alight: max-choices attribute; oldest selection is evicted when cap is exceeded

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: get_selected_result_label() / data-selected-html

Token separators for tags

no

yes

alight requires click or Enter; select2: data-token-separators (e.g. type , to commit)

Rich HTML result/selection templates

partial

yes

alight renders get_result_label() as raw HTML but has no separate selection template; select2: templateResult / templateSelection JS callbacks + data-html

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-choices enforcement 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.

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

  2. No selected_text — there is no mechanism to show a different label once an item is selected. The deck always shows get_result_label(). Select2’s get_selected_result_label() hook has no alight equivalent yet.

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