Widgets

This module provides the widget classes that render Tom Select elements in Django forms. These widgets handle both the HTML rendering and JavaScript initialization of Tom Select controls.

Model Widgets

Class Hierarchy

            classDiagram
        class TomSelectWidgetMixin {
            +template_name: str
            +render()
            +get_plugin_context()
            +get_autocomplete_url()
            +build_attrs()
            +media
        }

        class TomSelectModelWidget {
            +get_context()
            +get_queryset()
            +get_autocomplete_view()
            +validate_request()
        }

        class TomSelectModelMultipleWidget {
            +get_context()
            +build_attrs()
        }

        class TomSelectIterablesWidget {
            +get_context()
            +get_autocomplete_view()
            +get_iterable()
        }

        class TomSelectIterablesMultipleWidget {
            +get_context()
            +build_attrs()
        }

        TomSelectWidgetMixin <-- TomSelectModelWidget
        TomSelectWidgetMixin <-- TomSelectIterablesWidget
        TomSelectModelWidget <-- TomSelectModelMultipleWidget
        TomSelectIterablesWidget <-- TomSelectIterablesMultipleWidget
    

TomSelectModelWidget

class django_tomselect.widgets.TomSelectModelWidget(config=None, **kwargs)[source]

Bases: TomSelectWidgetMixin, Select

A Tom Select widget with model object choices.

Parameters:
__init__(config=None, **kwargs)[source]

Initialize widget with model-specific attributes.

Parameters:
Return type:

None

get_autocomplete_context()[source]

Get context for autocomplete functionality.

Return type:

dict[str, Any]

get_autocomplete_view()[source]

Get instance of autocomplete view for accessing queryset and search_lookups.

Return type:

AutocompleteModelView | None

get_context(name, value, attrs=None)[source]

Get context for rendering the widget.

Parameters:
Return type:

dict[str, Any]

get_instance_url_context(obj, autocomplete_view)[source]

Get URL-related context for a selected object.

Public subclass-override hook. Returns a dict mapping detail_url / update_url / delete_url to fully built URL strings, omitting keys that are not configured or not permitted. Dicts and instances with no pk return an empty mapping.

Parameters:
Return type:

dict[str, Any]

get_label_for_object(obj, autocomplete_view)[source]

Get the label for an object using the configured label field.

Parameters:
Return type:

str

get_model()[source]

Get model from field’s choices or queryset.

Return type:

type[Model] | None

get_model_url_context(autocomplete_view)[source]

Get URL-related context for a model object.

We retrieve & store list and create URLs, because they are model-specific, not instance-specific. These are used when initializing the widget, not when selecting an option.

Instance-specific URLs are stored in the selected_options.

Parameters:

autocomplete_view (AutocompleteModelView)

Return type:

dict[str, Any]

get_permissions_context(autocomplete_view)[source]

Get permission-related context for the widget.

Parameters:

autocomplete_view (AutocompleteModelView)

Return type:

dict[str, Any]

get_queryset()[source]

Get queryset from autocomplete view.

Return type:

QuerySet | None

get_search_lookups()[source]

Get search lookups from autocomplete view.

Return type:

list[str]

property media

Return the media for rendering the widget.

validate_request(request)[source]

Validate that a request object is valid for permission checking.

Parameters:

request (Any)

Return type:

bool

Example Usage

from django import forms
from django_tomselect.widgets import TomSelectModelWidget
from django_tomselect.app_settings import TomSelectConfig

class BookForm(forms.ModelForm):
    author = forms.ModelChoiceField(
        widget=TomSelectModelWidget(
            config=TomSelectConfig(
                url='author-autocomplete',
                show_detail=True,
                show_update=True
            )
        )
    )

TomSelectModelMultipleWidget

class django_tomselect.widgets.TomSelectModelMultipleWidget(config=None, **kwargs)[source]

Bases: TomSelectModelWidget, SelectMultiple

A TomSelect widget that allows multiple model object selection.

Parameters:
build_attrs(base_attrs, extra_attrs=None)[source]

Build HTML attributes for the widget.

Parameters:
Return type:

dict[str, Any]

get_context(name, value, attrs=None)[source]

Get context for rendering the widget.

Parameters:
Return type:

dict[str, Any]

property media

Return the media for rendering the widget.

Example Usage

from django_tomselect.app_settings import TomSelectConfig, PluginCheckboxOptions

class BookForm(forms.ModelForm):
    categories = forms.ModelMultipleChoiceField(
        widget=TomSelectModelMultipleWidget(
            config=TomSelectConfig(
                url='category-autocomplete',
                plugin_checkbox_options=PluginCheckboxOptions()
            )
        )
    )

Iterables Widgets

TomSelectIterablesWidget

class django_tomselect.widgets.TomSelectIterablesWidget(config=None, **kwargs)[source]

Bases: TomSelectWidgetMixin, Select

A Tom Select widget with iterables, TextChoices, or IntegerChoices choices.

Parameters:
get_autocomplete_context()[source]

Get context for autocomplete functionality.

Return type:

dict[str, Any]

get_autocomplete_view()[source]

Get instance of autocomplete view for accessing iterable.

Return type:

AutocompleteIterablesView | None

get_context(name, value, attrs=None)[source]

Get context for rendering the widget.

Parameters:
Return type:

dict[str, Any]

get_iterable()[source]

Get iterable or choices from autocomplete view.

Return type:

list | tuple | type

get_lazy_view()[source]

Get lazy-loaded view for the TomSelect iterables widget.

Return type:

LazyView | None

property media

Return the media for rendering the widget.

set_request(request)[source]

Iterables do not require a request object.

Parameters:

request (HttpRequest)

Return type:

None

Example Usage

from django.db.models import TextChoices

class Status(TextChoices):
    DRAFT = 'D', 'Draft'
    PUBLISHED = 'P', 'Published'
    ARCHIVED = 'A', 'Archived'

class ArticleForm(forms.Form):
    status = forms.ChoiceField(
        choices=Status.choices,
        widget=TomSelectIterablesWidget(
            config=TomSelectConfig(
                plugin_dropdown_header=PluginDropdownHeader(
                    title="Select Status"
                )
            )
        )
    )

TomSelectIterablesMultipleWidget

class django_tomselect.widgets.TomSelectIterablesMultipleWidget(config=None, **kwargs)[source]

Bases: TomSelectIterablesWidget, SelectMultiple

A TomSelect widget for multiple selection of iterables, TextChoices, or IntegerChoices.

Parameters:
build_attrs(base_attrs, extra_attrs=None)[source]

Build HTML attributes for the widget.

Parameters:
Return type:

dict[str, Any]

get_context(name, value, attrs=None)[source]

Get context for rendering the widget.

Parameters:
Return type:

dict[str, Any]

property media

Return the media for rendering the widget.

Example Usage

from django_tomselect.app_settings import TomSelectConfig, PluginRemoveButton

class ArticleForm(forms.Form):
    tags = forms.MultipleChoiceField(
        choices=[('python', 'Python'), ('django', 'Django'), ('web', 'Web Development')],
        widget=TomSelectIterablesMultipleWidget(
            config=TomSelectConfig(
                plugin_remove_button=PluginRemoveButton()
            )
        )
    )

Base Mixin

TomSelectWidgetMixin

class django_tomselect.widgets.TomSelectWidgetMixin(config=None, **kwargs)[source]

Bases: object

Mixin to provide methods and properties for all TomSelect widgets.

Parameters:
__init__(config=None, **kwargs)[source]

Initialize shared TomSelect configuration.

Parameters:
Return type:

None

build_attrs(base_attrs, extra_attrs=None)[source]

Build HTML attributes for the widget.

Parameters:
Return type:

dict[str, Any]

get_autocomplete_params()[source]

Hook for subclasses to specify additional autocomplete query parameters.

Override and return a URL-safe &-joined string (no leading &).

Return type:

str

get_autocomplete_url()[source]

Hook to specify the autocomplete URL.

Return type:

str

get_autocomplete_view()[source]

Get the autocomplete view. Overridden in subclasses.

Return type:

Any

get_csp_nonce()[source]

Get CSP nonce from the current request, if available.

Supports django-csp (request.csp_nonce) and any middleware that sets request._csp_nonce or request.csp_nonce.

Return type:

str | None

get_current_request()[source]

Get the current request from thread-local storage.

Return type:

HttpRequest | None

get_lazy_view()[source]

Get lazy-loaded view for the TomSelect widget.

Return type:

LazyView | None

get_model()[source]

Get the model class. Overridden in subclasses.

Return type:

type[Model] | None

get_plugin_context()[source]

Get context for plugins.

Return type:

dict[str, Any]

get_url(view_name, view_type='', **kwargs)[source]

Reverse the given view name and return the path.

Parameters:
  • view_name (str)

  • view_type (str)

  • kwargs (Any)

Return type:

str

get_url_param_constants()[source]

Get URL parameter constants for use in templates.

Returns a dictionary of URL parameter names that can be used in JavaScript for building autocomplete request URLs.

Return type:

dict[str, str]

property media: Media

Return the media for rendering the widget.

render(name, value, attrs=None, renderer=None)[source]

Render the widget.

Parameters:
Return type:

str

This mixin provides the core functionality for all TomSelect widgets, including:

  • Media handling (CSS/JS)

  • Template rendering

  • Configuration processing

  • Plugin support

Customization

Custom Rendering Templates

You can override the default rendering templates by creating your own templates in your project’s template directory under django_tomselect/render/. The available templates are:

  • clear_button.html: Renders the clear button plugin HTML

  • dropdown_footer.html: Renders the dropdown footer plugin HTML

  • dropdown_header.html: Renders the dropdown header plugin HTML

  • item.html: Renders selected items

  • loading_more.html: Renders the “Loading more results…” message

  • loading.html: Renders the loading spinner/indicator

  • no_more_results.html: Renders the message when no more results are available

  • no_results.html: Renders the message when no search results are found

  • not_loading.html: Renders content when not loading

  • optgroup_header.html: Renders the header for an option group

  • optgroup.html: Renders an option group container

  • option_create.html: Renders the “Create new option” element

  • option.html: Renders dropdown options

  • select.html: Renders the underlying select element

Custom Attributes

Widgets accept custom HTML attributes through the attrs parameter:

widget = TomSelectModelWidget(
    config=config,
    attrs={
        'class': 'custom-select',
        'data-custom': 'value',
        'data_template_option': '`<div>${data.name} (${data.id})</div>`',
        'data_template_item': '`<div>${data.name}</div>`'
    }
)

Media Configuration

The widgets automatically include the required CSS and JavaScript files. You can configure the CSS framework and whether to use minified files:

widget = TomSelectModelWidget(
    config=TomSelectConfig(
        css_framework='bootstrap5',  # 'default', 'bootstrap4', or 'bootstrap5'
        use_minified=True
    )
)

Note

Remember to include {{ form.media }} in your templates to include the required CSS and JavaScript files.

TomSelectTokenWidget

A token-style input that multiplexes multiple autocomplete views. Pairs with CompositeAutocompleteView (server) and TomSelectTokenField (form-level validation owner).

from django_tomselect import TomSelectTokenWidget

widget = TomSelectTokenWidget(
    composite_view="autocomplete-article-token",  # URL name
    placeholder="Filter articles…",
    allow_free_text=True,
    max_query_length=4096,   # utf-8 byte cap on the serialized value
    max_tokens=32,
    css_framework="bootstrap5",  # "default" | "bootstrap4" | "bootstrap5"
)

The widget is presentation-only - clean() lives on TomSelectTokenField in django_tomselect.forms. The serialized form value is a single token string (e.g. author:42 category:5 some free text) stored in a CharField.

See the Article Token-Style Search page for an end-to-end demo of the Operator configuration, server-side delegation, and chip rehydration.