Django Media assets in Forms,如何defer/async JS assets

Django Media assets in Forms, how to defer/async JS assets

official docs 解释了如何为某些小部件自动添加资产。,来自他们的示例:

from django import forms

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

它没有描述的是如何使JS资产延迟或异步加载,例如

    <script defer src="https://myserver.com/static/animations.js">/script>

您可以覆盖小部件的 js-renderer:

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

但是,它将与您应用程序的所有小部件相关。

更新: 但是如果你需要对每个 Widget 进行不同的渲染,我可以建议你使用以下技巧(使用 'private' 属性 来定义格式):

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