default_renderer is not accessible in BaseForm

15 views
Skip to first unread message

Ryan Burt

unread,
Apr 30, 2023, 11:41:38 AM4/30/23
to Django users
Hi all,

I upgraded from Django 3.2 to Django 4.2 and somewhere along the way, access to an overridden default_renderer in my ModelForm has been lost.

settings.py:

FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
 
my_app/forms.py:

class MyModelForm(forms.ModelForm):
    default_renderer = CustomRenderer
   
    class Meta:
        model = MyModel

The custom renderer adds some extra divs and formatting with row and column css classes and I only apply it to certain widgets on certain forms within one of my apps. I just point specific widgets to a custom html file.

This worked prior to the upgrade. I think the issue is in the forms api. Each time the code hits the following block in BaseForm.__init__(), renderer is always not none, regardless of if FORM_RENDERER is set explicitly or not:

(line 120 in forms/forms.py)
        # Initialize form renderer. Use a global default if not specified
        # either as an argument or as self.default_renderer.
        if renderer is None:
            if self.default_renderer is None:
                renderer = get_default_renderer()
            else:
                renderer = self.default_renderer
                if isinstance(self.default_renderer, type):
                    renderer = renderer()
        self.renderer = renderer

The code inside the if statement is never reached (granted I have only tried some non-exhaustive combinations).

I can see three solutions to this
1. Override the init in my model form and set renderer = None explicitly, so that the default_renderer is picked up instead (shameless dirty hack)

2. Make pr with a change to look for the default_renderer first:
        # Initialize form renderer. Use a global default if not specified
        # either as an argument or as self.default_renderer.
        if self.default_renderer:
            if isinstance(self.default_renderer, type):
                renderer = self.default_renderer()
            else:
                renderer = self.default_renderer
        elif renderer is None:
                renderer = get_default_renderer()
        self.renderer = renderer

3. change the project settings in the event that I have missed some crucial change between 3.2 and 4.2 that explains why the renderer is always not not in the BaseForm init.

I'd appreciate any help from any forms api experts that can point me in the right direction.

Cheers,
Ryan.
Reply all
Reply to author
Forward
0 new messages