Upgrading from 4.0.3 to 5.0.0¶
DAL 5.0.0 drops Django 4.2 support and requires Django 5.2 or newer. Upgrade Django first, then upgrade DAL without the v4 pin.
pip install -U django-autocomplete-light
Python API changes¶
If your project subclasses DAL classes or overrides DAL methods, check these changes.
BaseQuerySetView.post()¶
If you override BaseQuerySetView.post(), move the reusable create flow to
self._post(request).
In v4, BaseQuerySetView.post() checked permissions, read POST['text'],
optionally called validate(), created the object, and always returned
Select2 JSON.
In v5, BaseQuerySetView is shared by Select2 and
alight. _post(request) only returns the created object or an early
HttpResponse. Your backend-specific post() must format the final
response.
Select2-style override:
def post(self, request, *args, **kwargs):
result = self._post(request)
if isinstance(result, http.HttpResponse):
return result
return http.JsonResponse({
'id': self.get_result_value(result),
'text': self.get_selected_result_label(result),
})
For validation errors, catch django.core.exceptions.ValidationError around
self._post(request) and return the response shape your frontend expects.
See Select2QuerySetView.post() and AlightQuerySetView.post() for the
built-in implementations.
If you call super().post() from a Select2QuerySetView subclass, this
still returns Select2 JSON. If you call super().post() from a direct
BaseQuerySetView subclass, update the class to inherit from
Select2QuerySetView or implement post() using self._post().
Create-option hooks¶
If you override Select2ViewMixin.get_create_option(), keep returning a
Select2 result list, but use self._should_show_create(context, q) for the
common permission, page, empty-query, and duplicate-label checks. Override
BaseQuerySetView._should_show_create() instead if you want the same
create-option rule to apply to Select2 and alight.
v5 pattern:
def get_create_option(self, context, q):
if not self._should_show_create(context, q):
return []
return [{'id': q, 'text': 'Create "%s"' % q, 'create_id': True}]
If you set case_sensitive_create on a custom Select2ViewMixin subclass,
move it to the BaseQuerySetView / Select2QuerySetView subclass. The
attribute is now read by BaseQuerySetView._should_show_create().
Select2 widgets¶
dal_select2.widgets.Select2InitialRenderMixin was removed. If your
project imports or subclasses it, remove that dependency before upgrading.
Subclass the concrete widget you need instead:
Select2MultipleListSelect2ModelSelect2ModelSelect2Multiple
Selected values are now rendered by
filter_choices_to_render() for list-backed
widgets and
filter_choices_to_render() for
queryset-backed widgets.
If you overrode render() only to inject initial Select2 choices, delete
that override and rely on the built-in selected-choice filtering. If you still
need custom selected values for a list-backed widget, override
filter_choices_to_render(selected_choices) instead of render().
If you override WidgetMixin.filter_choices_to_render(), note that the
default implementation now keeps selected raw values even when they are absent
from self.choices by appending (value, value) pairs. Add your own
filtering before calling super() if your project must reject unknown
selected values during rendering.
List choice fields¶
If you import dal_select2.fields.ChoiceCallable, change the import to:
from dal.fields import ChoiceCallable
Select2ListChoiceField and Select2ListCreateChoiceField are still
available from dal_select2.fields.
If you subclass the Select2 list fields only to reuse their generic
list/callable-choice behavior, inherit from the new backend-neutral
dal.fields.ListChoiceField or dal.fields.ListCreateChoiceField. Keep
inheriting from dal_select2.fields.Select2ListChoiceField or
Select2ListCreateChoiceField when the class is specifically part of a
Select2 form API.
Widget forward lists¶
If you mutate widget.forward after widget construction and expected that
mutation to affect other forms sharing the same widget instance, pass the
complete forward= list when constructing each widget instead.
WidgetMixin now copies forward during construction and deepcopy, so
shared mutable forward lists no longer leak between form instances.
JavaScript changes¶
If your project only uses the bundled DAL static files through widget media, you normally do not need JavaScript changes for existing Select2 widgets. If you copied DAL JavaScript into your project, override the Select2 initialization function, or migrate widgets to alight, check these changes.
Migrating custom JavaScript from Select2 to alight¶
The new dal_alight backend does not use jQuery or Select2. It uses native
web components plus dal-django.js.
If you migrate a widget from Select2 to alight:
Replace Select2-specific event handlers such as
select2:selectingwith alight/web-component behavior or normal form field events.Do not expect autocomplete responses to be Select2 JSON. Alight queryset and list views return HTML fragments containing
data-valueoptions.Do not expect create-on-the-fly POST responses to be JSON. Alight create responses return a selected-option HTML fragment.
Keep using DAL
forwarddeclarations in Python.dal-django.jsreads the samedal-forward-confmarkup and appendsforwarddata to alight requests.Keep Django admin related-object popup behavior enabled through
dal-django.jsinstead of Select2-specific hooks.
For class-by-class migration from Select2 widgets and views to alight, see
upgrade_from_select2_to_alight.rst.
New alight Python APIs¶
The alight backend is optional. These APIs are exported from
dal.autocomplete when their apps are installed, matching the existing
Select2 convenience import style.
dal_alight.widgets:
ModelAlightModelAlightMultipleAlightAlightMultipleListAlightTagAlightTaggitAlight
dal_alight.views:
AlightQuerySetViewAlightGroupQuerySetViewAlightListViewAlightGroupListViewAlightTagAutocompleteView
dal_alight.fields:
AlightListChoiceFieldAlightListCreateChoiceField
dal_alight_queryset_sequence:
AlightQuerySetSequenceViewAlightQuerySetSequenceAutoViewQuerySetSequenceAlightQuerySetSequenceAlightMultipleAlightGenericForeignKeyModelField