[Django]-Django Media assets in Forms, how to defer/async JS assets?

5👍

You can override js-renderer of the widget:

forms.py

def render_js(cls):
    return [
        format_html(
            '<script defer src="{}"></script>',
            cls.absolute_path(path)
        ) for path in cls._js
    ]
forms.widgets.Media.render_js = render_js

However, it will be relevant for all widgets of your application.

UPD:
But if you need a different rendering per Widget, I can suggest you the following trick (use ‘private’ property to define a format):

class CalendarWidget(forms.TextInput):
    class Media:
        css = {
            'all': ('pretty.css',)
        }
        js = ('animations.js', 'actions.js', 'defer')

def render_js(cls):
    fmt = '<script src="{}"></script>'
    formats = {
        'defer': '<script defer src="{}"></script>'
    }

    for path in cls._js:
        if path in formats:
            fmt = formats[path]
            break

    return [
        format_html(
            fmt,
            cls.absolute_path(path)
        ) for path in cls._js if path not in formats
    ]
forms.widgets.Media.render_js = render_js

Leave a comment