Introduction
Forms can declare CSS and JavaScript dependencies via the Media class.
Key Concepts
Media Class: Declares form CSS/JS requirements.
Media Merging: Combining media from multiple forms.
Real World Context
When building a form with a custom date picker widget and a rich text editor, each widget needs its own CSS and JavaScript files. The Media class automates this: include {{ form.media }} in your template and Django handles deduplication and ordering.
Deep Dive
Defining Media
pythonclass DatePickerWidget(forms.TextInput): class Media: css = { 'all': ('css/datepicker.css',) } js = ('js/datepicker.js',) class MyForm(forms.Form): date = forms.DateField(widget=DatePickerWidget) class Media: css = {'all': ('css/forms.css',)} js = ('js/validation.js',)
Using Media in Templates
html<head> {{ form.media.css }} </head> <body> {{ form.as_p }} {{ form.media.js }} </body>
Combining Media
python# Multiple forms combined = form1.media + form2.media
Common Pitfalls
- Including
form.mediainside the form tag -- CSS links must go in<head>and scripts before</body>. Useform.media.cssandform.media.jsseparately. - Duplicate assets from multiple forms -- Use
form1.media + form2.mediawhich automatically deduplicates. - Forgetting to serve static files -- Media paths are relative to STATIC_URL. If static files are not configured, the assets will 404.
Best Practices
- Split CSS and JS placement -- Use
{{ form.media.css }}in<head>and{{ form.media.js }}before</body>. - Use the Media class on custom widgets, not forms -- This keeps assets scoped correctly when the widget is reused.
Summary
Use Media class to declare CSS/JS dependencies. Include form.media in templates. Media automatically combines from nested widgets.