3

The official docs explain how to automatically adds assets for certain widgets., from thier example:

from django import forms

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

What it does not describe is how to make JS assets deferred or async loaded, e.g.

    <script defer src="https://myserver.com/static/animations.js">/script>
run_the_race
  • 1,344
  • 2
  • 36
  • 62

1 Answers1

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
Egor Wexler
  • 1,754
  • 6
  • 22