Widgets Overview

Django Gentelella Widgets provides a comprehensive set of form widgets that replace Django’s default widgets with Bootstrap 5 styled, feature-rich alternatives.

Quick Start

Import widgets from the core module:

from djgentelella.widgets import core as genwidgets

Use them in your forms:

from django import forms
from djgentelella.forms.forms import GTForm
from djgentelella.widgets import core as genwidgets

class MyForm(GTForm, forms.Form):
    name = forms.CharField(widget=genwidgets.TextInput)
    email = forms.EmailField(widget=genwidgets.EmailInput)
    birth_date = forms.DateField(widget=genwidgets.DateInput)

Or with ModelForm:

class MyModelForm(GTForm, forms.ModelForm):
    class Meta:
        model = MyModel
        fields = ['name', 'email', 'country', 'description']
        widgets = {
            'name': genwidgets.TextInput,
            'email': genwidgets.EmailInput,
            'country': genwidgets.Select,
            'description': genwidgets.Textarea,
        }

Widget Categories

Core Inputs (djgentelella.widgets.core)

  • TextInput - Text input field

  • NumberInput - Integer input

  • FloatInput - Decimal input

  • EmailInput - Email field

  • URLInput - URL field

  • PasswordInput - Password field

  • HiddenInput - Hidden field

  • ColorInput - Color picker

  • Textarea - Multi-line text

Select Widgets (djgentelella.widgets.core)

  • Select - Single select dropdown (Select2)

  • SelectMultiple - Multi-select dropdown

  • SelectWithAdd - Select with add new option

  • SelectMultipleAdd - Multi-select with add new

  • RadioHorizontalSelect / RadioVerticalSelect - Radio buttons

  • NullBooleanSelect - Yes/No/Unknown

  • CheckboxInput - Single checkbox

  • CheckboxSelectMultiple - Multiple checkboxes

  • FilteredSelectMultiple (djgentelella.widgets.selectmultiple) - Two panel available/chosen picker, the filter_horizontal layout

Date/Time Widgets (djgentelella.widgets.core)

  • DateInput - Date picker

  • DateTimeInput - DateTime picker

  • TimeInput - Time picker

  • DateRangeInput - Date range selector

  • DateRangeInputCustom - Date range with presets

  • DateRangeTimeInput - DateTime range

  • SplitDateTimeWidget - Separate date/time inputs

  • SelectDateWidget - Dropdown date selector

Masked Inputs (djgentelella.widgets.core)

  • EmailMaskInput - Email with mask

  • PhoneNumberMaskInput - Phone with mask

  • DateMaskInput - Date with mask

  • CreditCardMaskInput - Credit card format

  • TaxIDMaskInput - Tax ID format

  • SerialNumberMaskInput - Serial number format

File Widgets (djgentelella.widgets.core and djgentelella.widgets.files)

  • FileInput - File upload with chunking

  • ClearableFileInput - File with clear option

  • FileChunkedUpload - Large file upload

  • ImageRecordInput - Camera capture

  • VideoRecordInput - Video recording

  • AudioRecordInput - Audio recording

Autocomplete Widgets (djgentelella.widgets.selects)

  • AutocompleteSelect - Single select with remote search

  • AutocompleteSelectMultiple - Multi-select with remote search

  • AutocompleteSelectImage - Image selection

  • AutocompleteSelectMultipleImage - Multiple image selection

Slider Widgets (djgentelella.widgets.core)

  • GridSlider - Range slider

  • SingleGridSlider - Single value slider

  • DateGridSlider - Date range slider

Special Widgets

  • YesNoInput - Toggle with field visibility control

  • NumberKnobInput - Circular knob input (djgentelella.widgets.numberknob)

  • TaggingInput / EmailTaggingInput - Tag inputs (djgentelella.widgets.tagging)

  • EditorTinymce - WYSIWYG editor (djgentelella.widgets.tinymce)

  • CalendarInput - Calendar widget (djgentelella.widgets.calendar)

  • DigitalSignatureInput - Digital signature (djgentelella.widgets.digital_signature)

Voice Widgets (speech-to-text dictation, see Voice dictation widgets)

  • VoiceDictation - Textarea with progressive voice dictation (djgentelella.widgets.core)

  • VoiceEditorTinymce - TinyMCE editor with voice dictation (djgentelella.widgets.tinymce)

Map Widgets (Leaflet, see Map widgets)

  • MapPointInput - Pick a GPS point on a map (djgentelella.widgets.maps)

  • DJMap - Dashboard map fed by an API (gentelella/widgets/djmap.html)

Visualization Widgets (readonly display)

  • UrlTimeLineInput - Timeline display (djgentelella.widgets.timeline)

  • UrlStoryLineInput - Storyline display (djgentelella.widgets.storyline)

  • MapBasedStoryMapInput - Map story (djgentelella.widgets.storymap)

  • GigaPixelStoryMapInput - High-res image story (djgentelella.widgets.storymap)

Tree Widgets (djgentelella.widgets.trees)

  • TreeSelect - Hierarchical single select

  • TreeSelectMultiple - Hierarchical multi-select

  • TreeSelectWithAdd - Tree select with add new

  • TreeSelectMultipleWithAdd - Tree multi-select with add new

Passing Attributes

All widgets accept an attrs parameter for HTML attributes:

class MyForm(GTForm, forms.Form):
    name = forms.CharField(
        widget=genwidgets.TextInput(attrs={
            'placeholder': 'Enter your name',
            'class': 'custom-class',
            'data-custom': 'value',
            'maxlength': 100,
        })
    )

Common attributes:

  • placeholder - Placeholder text

  • class - Additional CSS classes

  • data-* - Custom data attributes for JavaScript

  • disabled - Disable the input

  • readonly - Make read-only

API Reference

Core Widgets

class djgentelella.widgets.core.AudioRecordInput(attrs=None, extraskwargs=True)
class djgentelella.widgets.core.CheckboxInput(attrs=None)
class djgentelella.widgets.core.ClearableFileInput(attrs=None, extraskwargs=True)
class djgentelella.widgets.core.ColorInput(attrs=None, extraskwargs=True)
class djgentelella.widgets.core.CreditCardMaskInput(attrs=None, format=None)
class djgentelella.widgets.core.DateInput(attrs=None, format=None)

Warning

Set in settings

USE_L10N = False

DATE_INPUT_FORMATS=[ ‘%Y-%m-%d’,’%d/%m/%Y’,’%d/%m/%y’]

By limitation on js datetime widget format conversion

class djgentelella.widgets.core.DateMaskInput(attrs=None)
class djgentelella.widgets.core.DateRangeInput(attrs=None, format=None)
class djgentelella.widgets.core.DateRangeInputCustom(attrs=None, format=None)
class djgentelella.widgets.core.DateRangeTimeInput(attrs=None, format=None)
class djgentelella.widgets.core.DateTimeInput(attrs=None, format=None)

Warning

Set in settings

USE_L10N = False

DATETIME_INPUT_FORMATS=[ ‘%m/%d/%Y %H:%M %p’ ]

By limitation on js datetime widget format conversion

class djgentelella.widgets.core.DateTimeMaskInput(attrs=None)
class djgentelella.widgets.core.EmailInput(attrs=None, extraskwargs=True)
class djgentelella.widgets.core.EmailMaskInput(attrs=None)
class djgentelella.widgets.core.FileInput(attrs=None, extraskwargs=True)
format_value(value)

File input never renders a value.

value_from_datadict(data, files, name)

File widgets take data from FILES, not POST

class djgentelella.widgets.core.FloatInput(attrs=None, extraskwargs=True)
class djgentelella.widgets.core.HiddenInput(attrs=None, extraskwargs=True)
class djgentelella.widgets.core.ImageRecordInput(attrs=None, extraskwargs=True)

You can set the preview size using data-width and data-height.

class djgentelella.widgets.core.Input(attrs=None, extraskwargs=True)

Base class for all <input> widgets.

class djgentelella.widgets.core.NumberInput(attrs=None, extraskwargs=True)
class djgentelella.widgets.core.PasswordInput(attrs=None, extraskwargs=True)
class djgentelella.widgets.core.PhoneNumberMaskInput(attrs=None)
class djgentelella.widgets.core.PhoneNumberTwoDigitMaskInput(attrs=None)
class djgentelella.widgets.core.SelectDateWidget(attrs=None)
class djgentelella.widgets.core.SerialNumberMaskInput(attrs=None, format=None)
class djgentelella.widgets.core.SplitDateTimeWidget(attrs=None)
property media

Media for a multiwidget is the combination of all media of the subwidgets.

class djgentelella.widgets.core.SplitHiddenDateTimeWidget(attrs=None)
property media

Media for a multiwidget is the combination of all media of the subwidgets.

class djgentelella.widgets.core.TaxIDMaskInput(attrs=None, format=None)
class djgentelella.widgets.core.TextInput(attrs=None, extraskwargs=True)
class djgentelella.widgets.core.TimeInput(attrs=None, format=None)
class djgentelella.widgets.core.URLInput(attrs=None, extraskwargs=True)
class djgentelella.widgets.core.VideoRecordInput(attrs=None, extraskwargs=True)

You can set the preview size using data-width and data-height.

Note

Size of video depends on camera default configuration.

class djgentelella.widgets.core.VoiceDictation(attrs=None, extraskwargs=True, url=None, language=None)

Textarea with a continuous dictation button: captures audio in the browser (Web Audio + VAD) and, as the user speaks, posts each speech segment to a transcription endpoint that returns {"text": "..."}; segments are inserted live. data-mode selects the strategy: segments (default, live), single (one request on stop) or hybrid (live segments then a whole-file rewrite on stop).

Two kwargs, the rest through attrs: url is the transcription endpoint (voice_transcribe or a proxy) and language sets data-language. Everything else is configured with plain data- attributes, which is deliberate – the javascript reads them straight off the element, so a project can add its own without the widget growing a kwarg for each one, and a template can override one per field:

VoiceDictation(url=reverse_lazy('voice_transcribe'),
               language='es',
               attrs={'data-mode': 'single'})

The ones the shipped engine understands:

Data-mode:

dictation strategy – segments (default, transcribes each speech segment live), single (one request when the user stops) or hybrid (live segments, then a whole-file rewrite on stop). An unknown value falls back to segments.

Data-hotwords:

comma separated words to bias the recogniser towards.

Data-initial-prompt:

free text giving the recogniser context.

Capture tuning, all numeric and all optional – the defaults live in the engine, and these are the seven keys voiceVadConfig reads (gentelella/js/base/voiceprogressive.js): data-vad-silence-ms, data-vad-min-speech-ms, data-vad-max-segment-ms, data-rms-threshold, data-pool-size, data-max-session-ms and data-request-timeout-ms.

hotwords and initial_prompt only reach a remote backend that was configured to accept them; the bundled Parakeet backend ignores both.

class djgentelella.widgets.core.YesNoInput(attrs=None, shparent='.form-group')

Tree Widgets

Django Gentelella uses django-tree-queries for tree database representations.

TinyMCE Widget

class djgentelella.widgets.tinymce.VoiceEditorTinymce(attrs=None, extraskwargs=True, url=None, language=None)

TinyMCE editor with a microphone button in its own toolbar for continuous voice dictation. Captures audio in the browser (Web Audio + VAD) and, as the user speaks, posts each speech segment to a transcription endpoint returning {"text": "..."}; segments are inserted live via editor.insertContent.

Configured exactly like VoiceDictation – same engine, same attributes. url and language are kwargs; data-mode (segments | single | hybrid), data-hotwords, data-initial-prompt and the seven capture-tuning keys go through attrs, so a project can add its own data- without the widget growing a kwarg per option:

VoiceEditorTinymce(url=reverse_lazy('voice_transcribe'),
                   attrs={'data-mode': 'hybrid'})

See VoiceDictation for what each attribute does.

Voice dictation ASR

Transcription endpoint (voice_transcribe) and the optional in-process Parakeet-v3 backend. See Voice dictation widgets for usage and settings.

class djgentelella.voice.views.VoiceTranscribeView(**kwargs)

Transcription endpoint for the voice dictation widgets, with two interchangeable backends selected by settings:

  • local — in-process Parakeet-v3 (needs pip install "djgentelella[asr]"). Use when the load is light.

  • remote — forward the audio to an external ASR HTTP API (needs pip install "djgentelella[asr-remote]" and GENTELELLA_ASR_REMOTE_URL). Use when you need more power than the host can provide in-process. When GENTELELLA_ASR_REMOTE_TOKEN is set, gentelella presents it as an Authorization: Bearer <token> header (the external API should always require one).

Backend selection (GENTELELLA_ASR_BACKEND): if unset, defaults to remote when GENTELELLA_ASR_REMOTE_URL is configured, otherwise local.

Accepts a POST with the audio in the file field (plus optional language, hotwords and initial_prompt; language drives the local backend and is forwarded to the remote one, the others are forwarded to remote backends that support them) and returns {"text": ...}.

Uploads larger than GENTELELLA_ASR_MAX_UPLOAD_BYTES (25 MB by default) are rejected with a 413: transcription is expensive in both backends (CPU in-process, billable API calls remotely) and each request holds a worker for up to GENTELELLA_ASR_TIMEOUT seconds.

The view requires an authenticated user and enforces it itself, so it must not be wrapped in login_required: that redirects, and the widget’s fetch would follow the 302 and choke on the login page in .json().

get_backend()

Resolve the configured backend, failing loudly on a typo.

Both settings are commonly wired to os.getenv, which yields '' rather than leaving the setting out, so an empty value counts as unset.

Optional in-process Parakeet-v3 ASR for the voice dictation widgets.

Requires the asr extra:

pip install "djgentelella[asr]"   # onnx-asr[cpu,hub] + av + numpy

Everything heavy (onnx_asr, av, numpy) is imported lazily so importing djgentelella stays free on installs without the extra. The model is loaded once per process (first request pays a ~670 MB download from Hugging Face and the warm-up cost); onnxruntime inference is thread-safe, so only the load is locked.

Configurable via settings:

  • GENTELELLA_ASR_MODEL (default "nemo-parakeet-tdt-0.6b-v3")

  • GENTELELLA_ASR_QUANTIZATION (default "int8")

  • GENTELELLA_ASR_LANGUAGE (default "es")

  • GENTELELLA_ASR_PNC (default True) – punctuation & capitals

Note: Parakeet does not support hotwords/initial_prompt biasing; those widget attrs are ignored by this backend.

djgentelella.voice.asr.decode_to_f32_16k(source)

Decode any container/codec PyAV supports (webm/opus, ogg, wav, …) to a float32 mono 16 kHz waveform normalized to [-1, 1]. source may be a file path or a file-like object with read().

djgentelella.voice.asr.transcribe(source, language=None)

Decode source and return the transcribed text (empty string if the audio has no decodable samples).

language defaults to GENTELELLA_ASR_LANGUAGE. Whatever it resolves to is also passed to the model as target_language, which is what stops Parakeet-v3 from translating to English instead of transcribing. Punctuation & capitals (GENTELELLA_ASR_PNC) are on by default.

Map Widgets

Leaflet based GPS point picker and dashboard map. See Map widgets for usage, the use_maps flag and the API JSON contract.

class djgentelella.widgets.maps.MapPointInput(attrs=None, extraskwargs=True, zoom=None, center=None, height=None, search=False, locate=True, based_fields=None, based_overwrite=False, tile_url=None, tile_attribution=None, geocoder_url=None)

Text input backed by a Leaflet map for picking a single GPS point.

The value is the plain string "lat,lng" – no GeoDjango, GDAL or PostGIS involved, so it works on SQLite. The point can be set by clicking the map, dragging the marker, typing into the input, the “use my location” button or, when enabled, an address search.

Unlike the read-only viewers in this library (UrlTimeLineInput, MapBasedStoryMapInput) this widget submits a value, so required and disabled are deliberately left alone.

Parameters:
  • zoom – initial zoom level

  • center – "lat,lng" or a (lat, lng) pair used when there is no value yet

  • height – CSS height for the map container, e.g. "400px"

  • search – show the address search box. Off by default – it geocodes through Nominatim, whose usage policy caps callers at 1 req/s and forbids heavy automated use.

  • locate – show the “use my location” button (hidden by the JS anyway outside a secure context, where the browser refuses to answer)

  • based_fields – CSS selectors of fields whose values are joined and geocoded to place the marker, e.g. ['#id_country', '#id_city']

  • based_overwrite – let based_fields move a point the user already placed. Off by default.

  • tile_url – tile layer template, defaults to OpenStreetMap

  • tile_attribution – attribution line for tile_url. Most tile providers require one, so set it whenever you set tile_url.

  • geocoder_url – Nominatim compatible endpoint, for self-hosting

djgentelella.fields.maps.DEFAULT_MAX_LENGTH = 63

Room for “-12.345678,-123.456789” plus a little slack.

class djgentelella.fields.maps.GTPointField(*args, zoom=None, center=None, based_fields=None, search=False, map_attrs=None, **kwargs)

Model field storing a GPS point as the string "lat,lng".

A plain CharField, so no GeoDjango, GDAL or PostGIS is needed and it works on SQLite. Use parse_point(obj.location) to get numbers back.

The map options (zoom, center, based_fields…) are forwarded to MapPointInput by formfield().

deconstruct()

Re-emit the extra kwargs so migrations round-trip.

django-location-field omits this, which makes its model fields undeconstructible; makemigrations --check (run by make sdist) would catch that here.

formfield(**kwargs)

Return a django.forms.Field instance for this field.

class djgentelella.fields.maps.GTPointFormField(*, max_length=None, min_length=None, strip=True, empty_value='', **kwargs)

Form field for a "lat,lng" point, rendered with a Leaflet map.

to_python(value)

Return a string.

widget

alias of MapPointInput

djgentelella.fields.maps.LATLNG_ERRORS = {'invalid_format': "Enter a point as 'latitude,longitude'.", 'invalid_latitude': 'Latitude must be between -90 and 90.', 'invalid_longitude': 'Longitude must be between -180 and 180.', 'invalid_number': 'Latitude and longitude must be numbers.'}

One message per failure mode, keyed by the ValidationError code validate_latlng raises.

djgentelella.fields.maps.parse_point(value)

"lat,lng" -> (lat, lng) floats, or None when unparseable.

Deliberately strict, so a malformed value is reported instead of being coerced into a plausible-looking point somewhere else on the planet.

djgentelella.fields.maps.validate_latlng(value)

Validator with one message per failure mode, not a single generic one.

class djgentelella.views.maps.BaseMapView(**kwargs)

Serves the point payload the DJMap javascript widget draws.

DJMap has no python widget class: a template includes gentelella/widgets/djmap.html and points it at this view’s URL.

Subclass it in <app>/gtmaps.py, override the hooks and register it:

@register_lookups(prefix="places", basename="placesmap")
class PlacesMap(BaseMapView):
    def get_layers(self):
        return [{"name": "Offices", "points": [
            {"lat": 9.93, "lng": -84.09, "popup": "<b>HQ</b>"},
        ]}]

Then point the widget at reverse_lazy('placesmap-list').

Filters sent by the widget arrive in self.request.query_params; narrow the queryset inside the hooks, the same contract the chart getters use.

No permission_classes here on purpose: this is a base class meant to be combined, and the subclass – or the viewset it is mixed into – is what declares the authentication and permissions, the same way BaseTimelineView does. Whatever get_layers() returns is served to whoever can reach the URL, so a subclass over a non-public queryset has to say so.

get_center()

[lat, lng], or None to fit the map to the points instead.

get_cluster()

Default clustering for layers that do not state their own.

serializer

alias of GTMapSerializer