I think my preferred solution would be to insert a call to a form renderer
method in the callchain between `BoundField.as_widget()` and
`Widget.render()`, which can be overridden by a custom renderer. It should
receive the `BoundField` itself as an argument so that it has access to
the current state. Something like the following sketch:
{{{#!python
class BoundField:
def as_widget(self, widget=None, attrs=None, only_initial=False):
... # leave current code as-is, except for last call to
widget.render()
return self.form.renderer.render_widget(
field=self,
widget=widget,
name=self.html_initial_name if only_initial else
self.html_name,
value=value,
attrs=attrs,
)
class BaseRenderer:
def render_widget(self, field, widget, name, value, attrs=None):
# this can be overridden to add/change/remove `attrs`, or to
render the widget in an entirely different way
return widget.render(name, value, attrs)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/35192>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* cc: David Smith (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/35192#comment:1>
* status: new => closed
* resolution: => needsinfo
Comment:
>it's currently almost impossible to add an invalid CSS class to widgets
that have errors.
I agree that it is currently tricky to add invalid CSS to widgets
(`<inputs>`) and would like to see this eased with Django itself. That was
one of my conclusions when I attempted to write a tailwind styled form
using just Django itself. See
[https://smithdc.uk/blog/2023/bootstrap_form_in_vanilla_django/ blog
post].
I think there's a few different design options here, in addition to your
suggestion above I see a couple of additional options.
- A template filter/tag. This is the approach used by both django-widget-
tweaks and django-crispy-forms.
- Easing use of a custom `BoundField`. Currently you need to override each
field's `get_bound_field()` to achieve this. Maybe this could also be set
on the form renderer? This would also allow folk to make other
customisations such as #35191 without adding a long list of options to the
renderer.
It's probably worth starting a discussion on the django forum to gain
wider views from the community. I'm happy to help with this discussion. As
I think we need a wider discussion on the design I'll mark as 'needsinfo'
for now.
--
Ticket URL: <https://code.djangoproject.com/ticket/35192#comment:2>