django-bs

Bootstrap integration for django using widget templates
git clone https://git.ce9e.org/django-bs.git

commit
6d4d3581d3c4e43e9b4e348a6bec60baed98d3fe
parent
a73b125ef982c8cf417bb0adc183ebf4e7832bfe
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2026-01-14 15:57
fix: avoid duplicate class attributes

relevant for multi selects in the admin UI

Diffstat

M django_bs/templates/django/forms/widgets/checkbox.html 3 ++-
M django_bs/templates/django/forms/widgets/input.html 3 ++-
M django_bs/templates/django/forms/widgets/select.html 3 ++-
M django_bs/templates/django/forms/widgets/textarea.html 3 ++-
M django_bs/templatetags/bootstrap.py 8 ++++++++

5 files changed, 16 insertions, 4 deletions


diff --git a/django_bs/templates/django/forms/widgets/checkbox.html b/django_bs/templates/django/forms/widgets/checkbox.html

@@ -1 +1,2 @@
    1    -1 <input type="{{ widget.type }}" name="{{ widget.name }}" class="form-check-input" {% if widget.value != None %}value="{{ widget.value|stringformat:'s' }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}>
   -1     1 {% load bootstrap %}
   -1     2 <input type="{{ widget.type }}" name="{{ widget.name }}" {% if widget.value != None %}value="{{ widget.value|stringformat:'s' }}"{% endif %}{% bootstrap_attrs class="form-check-input" %}>

diff --git a/django_bs/templates/django/forms/widgets/input.html b/django_bs/templates/django/forms/widgets/input.html

@@ -1 +1,2 @@
    1    -1 <input type="{{ widget.type }}" name="{{ widget.name }}" class="form-control" {% if widget.value != None %}value="{{ widget.value|stringformat:'s' }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}>
   -1     1 {% load bootstrap %}
   -1     2 <input type="{{ widget.type }}" name="{{ widget.name }}" {% if widget.value != None %}value="{{ widget.value|stringformat:'s' }}"{% endif %}{% bootstrap_attrs class="form-control" %}>

diff --git a/django_bs/templates/django/forms/widgets/select.html b/django_bs/templates/django/forms/widgets/select.html

@@ -1,4 +1,5 @@
    1    -1 <select name="{{ widget.name }}" class="form-select"{% include "django/forms/widgets/attrs.html" %}>
   -1     1 {% load bootstrap %}
   -1     2 <select name="{{ widget.name }}"{% bootstrap_attrs class="form-select" %}>
    2     3     {% for group_name, group_choices, group_index in widget.optgroups %}
    3     4         {% if group_name %}
    4     5             <optgroup label="{{ group_name }}">

diff --git a/django_bs/templates/django/forms/widgets/textarea.html b/django_bs/templates/django/forms/widgets/textarea.html

@@ -1,2 +1,3 @@
    1    -1 <textarea name="{{ widget.name }}" class="form-control"{% include "django/forms/widgets/attrs.html" %}>
   -1     1 {% load bootstrap %}
   -1     2 <textarea name="{{ widget.name }}"{% bootstrap_attrs class="form-control" %}>
    2     3 {% if widget.value %}{{ widget.value }}{% endif %}</textarea>

diff --git a/django_bs/templatetags/bootstrap.py b/django_bs/templatetags/bootstrap.py

@@ -94,6 +94,14 @@ def bootstrap_messages(context):
   94    94     return context
   95    95 
   96    96 
   -1    97 @register.inclusion_tag('django/forms/widgets/attrs.html', takes_context=True)
   -1    98 def bootstrap_attrs(context, **kwargs):
   -1    99     attrs = {**context['widget']['attrs']}
   -1   100     for key, value in kwargs.items():
   -1   101         attrs[key] = f'{value} {attrs.get(key, "")}'.strip()
   -1   102     return {'widget': {'attrs': attrs}}
   -1   103 
   -1   104 
   97   105 @register.inclusion_tag('bs/pagination.html', takes_context=True)
   98   106 def bootstrap_pagination(
   99   107     context,