Package: wagtailmedia
wagtailmediaA module for Wagtail that provides functionality similar towagtail.documentsmodule,
but for audio and video files.InstallInstall using pip:pipinstallwagtailmediawagtailmediais compatible with Wagtail 4.1 and above. Check out older releases for compatibility with older versions of Wagtail.SettingsIn your settings file, addwagtailmediatoINSTALLED_APPS:INSTALLED_APPS=[# ..."wagtailmedia",# ...]All wagtailmedia settings are defined in a singleWAGTAILMEDIAdictionary in your settings file. The
defaults are:# settings.pyWAGTAILMEDIA={"MEDIA_MODEL":"wagtailmedia.Media",# string, dotted-notation."MEDIA_FORM_BASE":"",# string, dotted-notation. Defaults to an empty string"AUDIO_EXTENSIONS":["aac","aiff","flac","m4a","m4b","mp3","ogg","wav",],# list of extensions"VIDEO_EXTENSIONS":["avi","h264","m4v","mkv","mov","mp4","mpeg","mpg","ogv","webm",],# list of extensions}URL configurationYour project needs to be set up to serve user-uploaded files fromMEDIA_ROOT.
Your Django project may already have this in place, but if not, add the following snippet tourls.py:fromdjango.confimportsettingsfromdjango.conf.urls.staticimportstaticurlpatterns=[# ... the rest of your URLconf goes here ...]+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)Note that this only works in development mode (DEBUG = True);
in production, you will need to configure your web server to serve files fromMEDIA_ROOT.
For further details, see the Django documentation:Serving files uploaded by a user during developmentandDeploying static files.With this configuration in place, you are ready to run./manage.py migrateto create the database tables used bywagtailmedia.wagtailmedialoads additional assets for the chooser panel interface.
Run./manage.py collectstaticafter the migrations step to collect all the required assets.CustomMediamodelTheMediamodel can be customised. To do this, you need
to add a new model to your project that inherits fromwagtailmedia.models.AbstractMedia.Then set theMEDIA_MODELattribute in theWAGTAILMEDIAsettings dictionary to point to it:# settings.pyWAGTAILMEDIA={"MEDIA_MODEL":"my_app.CustomMedia",# ...}You can customize the model form used with yourMediamodel using theMEDIA_FORM_BASEsetting.
It should be the dotted path to the form and will be used as the base form passed tomodelform_factory()when constructing the media form.# settings.pyWAGTAILMEDIA={"MEDIA_FORM_BASE":"my_app.forms.CustomMediaForm",# ...}Hooksconstruct_media_chooser_querysetCalled when rendering the media chooser view, to allow the media listing QuerySet to be customised.
The callable passed into the hook will receive the current media QuerySet and the request object,
and must return a Media QuerySet (either the original one, or a new one).fromwagtailimporthooks@hooks.register("construct_media_chooser_queryset")defshow_my_uploaded_media_only(media,request):# Only show uploaded mediamedia=media.filter(uploaded_by_user=request.user)returnmediaHow to useAs a regular Django fieldYou can useMediaas a regular Django field. Here’s an example:fromdjango.dbimportmodelsfromwagtail.fieldsimportRichTextFieldfromwagtail.modelsimportPagefromwagtail.admin.panelsimportFieldPanelfromwagtailmedia.edit_handlersimportMediaChooserPanelclassBlogPageWithMedia(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"),]TheMediaChooserPanelaccepts themedia_typekeyword argument (kwarg) to limit the types of media that can be chosen or uploaded.
At the moment only "audio" (MediaChooserPanel(media_type="audio")) and "video" (MediaChooserPanel(media_type="audio")) are supported,
and any other type will make the chooser behave as if it did not get any kwarg.Name clash with WagtailDo not name the fieldmedia. When rendering the admin UI, Wagtail uses amediaproperty for its fields’ CSS & JS assets loading.
Usingmediaas a field name breaks the admin UI (#54).In StreamFieldYou can useMediain StreamField. To do this, you need
to add a new block class that inherits fromwagtailmedia.blocks.AbstractMediaChooserBlockand implement your ownrender_basicmethod.Here is an example:fromdjango.dbimportmodelsfromdjango.forms.utilsimportflatattfromdjango.utils.htmlimportformat_html,format_html_joinfromwagtailimportblocksfromwagtail.admin.panelsimportFieldPanelfromwagtail.fieldsimportStreamFieldfromwagtail.modelsimportPagefromwagtailmedia.blocksimportAbstractMediaChooserBlockclassTestMediaBlock(AbstractMediaChooserBlock):defrender_basic(self,value,context=None):ifnotvalue:return""ifvalue.type=="video":player_code="""<div><video width="{1}" height="{2}" controls>{0}Your browser does not support the video tag.</video></div>"""else:player_code="""<div><audio controls>{0}Your browser does not support the audio element.</audio></div>"""returnformat_html(player_code,format_html_join("\n","<source{0}>",[[flatatt(s)]forsinvalue.sources]),value.width,value.height,)classBlogPage(Page):author=models.CharField(max_length=255)date=models.DateField("Post date")body=StreamField([("heading",blocks.CharBlock(classname="title",icon="title")),("paragraph",blocks.RichTextBlock(icon="pilcrow")),("media",TestMediaBlock(icon="media")),])content_panels=Page.content_panels+[FieldPanel("author"),FieldPanel("date"),FieldPanel("body"),]You can also use audio or video-specific choosers:# ...fromwagtail.modelsimportPagefromwagtail.fieldsimportStreamFieldfromwagtailmedia.blocksimportAudioChooserBlock,VideoChooserBlockclassBlogPage(Page):# ...body=StreamField([# ... other block definitions("audio",AudioChooserBlock()),("video",VideoChooserBlock()),])APITo expose media items in the API, you can follow theWagtail documentation guidefor API configuration with wagtailmedia specifics:# api.pyfromwagtail.api.v2.routerimportWagtailAPIRouterfromwagtailmedia.api.viewsimportMediaAPIViewSet# Register the routerapi_router=WagtailAPIRouter("wagtailapi")# add any other enpoints you need, plus the wagtailmedia oneapi_router.register_endpoint("media",MediaAPIViewSet)Translationswagtailmedia has translations in French and Chinese. More translations welcome!ContributingAll contributions are welcome!InstallTo make changes to this project, first clone this repository:gitclonegit@github.com:torchbox/wagtailmedia.gitcdwagtailmediaWith your preferred virtualenv activated, install testing dependencies:pipinstall-e'.[testing]'-Upre-commitNote that this project usespre-commit. To set up locally:# if you don't have it yet, globally$pipinstallpre-commit# go to the project directory$cdwagtailmedia# initialize pre-commit$pre-commitinstall# Optional, run all checks once for this, then the checks will run only on the changed files$pre-commitrun--all-filesHow to run testsNow you can run tests as shown below:toxor, you can run them for a specific environmenttox -e py310-dj41-wagtail41or specific testtox -e py310-dj41-wagtail41 -- tests.test_views.TestMediaChooserUploadViewTo run the test app interactively, usetox -e interactive, visithttp://127.0.0.1:8020/admin/and log in withadmin/changeme.