wagtailmedia

repository·main·Indexed 42 days ago

https://github.com/torchbox/wagtailmedia

A Wagtail module for managing and choosing audio and video files, similar to the built-in documents module. It provides specialized functionality including MediaChooserPanel for pages, AudioChooserBlock and VideoChooserBlock for StreamFields, and support for Wagtail API v2 and experimental API v3 (for Wagtail 8.0+). Compatible with Wagtail 7.0 and above, Python 3.10-3.14, and Django 5.2, 6.0, and 6.1.

Tokens
6.4K
Snippets
27
Records
39
Agent score
51%

What's inside wagtailmedia

  1. Configure URL routing for media files

    main

    To serve user-uploaded files during development, ensure your urls.py includes the static helper for MEDIA_URL and MEDIA_ROOT.

    Note: This is for development (DEBUG = True) only. In production, configure your web server (e.g., Nginx) to serve files from MEDIA_ROOT directly.

    from django.conf import settings
    from django.conf.urls.static import static
    
    urlpatterns = (
        # ... the rest of your URLconf goes here ...
    ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
  2. Use Media in StreamField

    main

    To use media in a StreamField, you have two options:

    1. Specific Chooser Blocks: Use the built-in AudioChooserBlock or VideoChooserBlock for simple selection.
    2. Custom Media Block: Inherit from wagtailmedia.blocks.AbstractMediaChooserBlock and implement render_basic to define how the media (e.g., <video> or <audio> tags) is rendered in the frontend.
    from wagtail import blocks
    from wagtail.fields import StreamField
    from wagtail.models import Page
    from wagtailmedia.blocks import AudioChooserBlock, VideoChooserBlock
    
    class BlogPage(Page):
        body = StreamField([
            ("audio", AudioChooserBlock()),
            ("video", VideoChooserBlock()),
        ])
  3. Customize the Media model and form

    main

    You can extend the default media functionality by creating a custom model that inherits from wagtailmedia.models.AbstractMedia.

    1. Define your custom model.
    2. Update WAGTAILMEDIA["MEDIA_MODEL"] with the dotted path to your model.
    3. (Optional) To customize the media model form, set WAGTAILMEDIA["MEDIA_FORM_BASE"] to the dotted path of your custom form class.
    # settings.py
    WAGTAILMEDIA = {
        "MEDIA_MODEL": "my_app.CustomMedia",
        "MEDIA_FORM_BASE": "my_app.forms.CustomMediaForm",
    }
  4. Configure wagtailmedia settings

    main

    After installing, add wagtailmedia to your INSTALLED_APPS. All configuration is managed via a single WAGTAILMEDIA dictionary in your settings.py file.

    Default Configuration Keys:

    • MEDIA_MODEL: (string, dotted-notation) The model used for media. Defaults to "wagtailmedia.Media".
    • MEDIA_FORM_BASE: (string, dotted-notation) The base form used for the media model. Defaults to an empty string.
    • AUDIO_EXTENSIONS: (list of strings) Allowed audio file extensions.
    • VIDEO_EXTENSIONS: (list of strings) Allowed video file extensions.
    • ENABLE_API_V3: (boolean) Enables the experimental Wagtail 8.0+ API v3 endpoints. Defaults to False.
    # settings.py
    
    INSTALLED_APPS = [
        # ...
        "wagtailmedia",
        # ...
    ]
    
    WAGTAILMEDIA = {
        "MEDIA_MODEL": "wagtailmedia.Media",
        "MEDIA_FORM_BASE": "",
        "AUDIO_EXTENSIONS": [
            "aac", "aiff", "flac", "m4a", "m4b", "mp3", "ogg", "wav",
        ],
        "VIDEO_EXTENSIONS": [
            "avi", "h264", "m4v", "mkv", "mov", "mp4", "mpeg", "mpg", "ogv", "webm",
        ],
        "ENABLE_API_V3": False,
    }
  5. Use Media as a regular Django field

    main

    To add a media selection field to a Wagtail Page, use a ForeignKey to wagtailmedia.Media and include a MediaChooserPanel in your content_panels.

    Important: Do not name your field media. This clashes with Wagtail's internal media property used for loading CSS/JS assets and will break the admin UI.

    You can restrict the chooser to specific types using the media_type argument in MediaChooserPanel (supports "audio" or "video").

    from django.db import models
    from wagtail.fields import RichTextField
    from wagtail.models import Page
    from wagtail.admin.panels import FieldPanel
    from wagtailmedia.edit_handlers import MediaChooserPanel
    
    class BlogPageWithMedia(Page):
        author = models.CharField(max_length=255)
        date = models.DateField("Post date")
        body = RichTextField(blank=False)
        featured_media = models.ForeignKey(
            "wagtailmedia.Media",
            null=True,
            blank=True,
            on_delete=models.SET_NULL,
            related_name="+",
        )
    
        content_panels = Page.content_panels + [
            FieldPanel("author"),
            FieldPanel("date"),
            FieldPanel("body"),
            MediaChooserPanel("featured_media", media_type="video"),
        ]
  6. Filter the media chooser queryset using hooks

    main

    Use the construct_media_chooser_queryset hook to customize the list of media items shown in the media chooser view. The hook receives the current Media QuerySet and the request object, and must return a Media QuerySet.

    from wagtail import hooks
    
    @hooks.register("construct_media_chooser_queryset")
    def show_my_uploaded_media_only(media, request):
        # Only show media uploaded by the current user
        media = media.filter(uploaded_by_user=request.user)
        return media
  7. Expose media via API v3 (Experimental)

    main

    For Wagtail 8.0+, you can opt-in to the experimental API v3 (powered by django-ninja) by setting ENABLE_API_V3: True in your WAGTAILMEDIA settings. The media endpoint will be available at <v3 API root>/media/.

    # settings.py
    WAGTAILMEDIA = {
        "ENABLE_API_V3": True,
    }
  8. Expose media via API v2

    main

    To expose media items through Wagtail's API v2, register the MediaAPIViewSet with your WagtailAPIRouter.

    from wagtail.api.v2.router import WagtailAPIRouter
    from wagtailmedia.api.views import MediaAPIViewSet
    
    api_router = WagtailAPIRouter("wagtailapi")
    api_router.register_endpoint("media", MediaAPIViewSet)
  9. Override the default Media form

    main

    You can customize the base form used for media management by setting MEDIA_FORM_BASE in your wagtailmedia_settings. This allows you to provide a custom Django form class that will be used by get_media_form(). If no override is provided, BaseMediaForm is used by default, which includes specialized widgets for tags, file, and thumbnail.

    # In your settings.py
    WAGTAILMEDIA_SETTINGS = {
        'MEDIA_FORM_BASE': 'path.to.your.CustomMediaForm',
    }
  10. Configure file upload restrictions via extensions

    main

    To restrict the types of files users can upload via the media forms, configure the allowed extensions in your wagtailmedia_settings. The get_media_form function will use these to set the accept attribute on the HTML file input. If no extensions are provided, it defaults to the browser's standard video/* or audio/* MIME types.

    # In your settings.py
    WAGTAILMEDIA_SETTINGS = {
        'VIDEO_EXTENSIONS': ['mp4', 'webm'],
        'AUDIO_EXTENSIONS': ['mp3', 'wav'],
    }