Skip to main content

🖼️ Media library

The media library is where editors upload and organize files: images, video, audio and documents, in folders. Fields such as MediaField then pick files from it. The library works with your own media models, or with the ready-made models Content Studio ships.

Set it up with your own models​

Point the settings at a media item model and, optionally, a folder model:

# mysite/settings.py
CONTENT_STUDIO = {
"MEDIA_LIBRARY_MODEL": "blog.models.MediaItem",
"MEDIA_LIBRARY_FOLDER_MODEL": "blog.models.MediaFolder",
}

A media item model needs these fields:

  • file: the upload, a FileField or ImageField.
  • name: shown on the item and used by the search.
  • type: one of "image", "video", "audio" or "file"; it decides the preview.
  • tags (optional): a list of strings, such as a JSONField, an ArrayField or the built-in TagField. Searched together with the name.
  • A focal point field (optional): a JSONField, named in FOCAL_POINT_ATTR.

A folder model needs a name and a parent foreign key to itself. System check content_studio.W007 reports missing fields. Without the MEDIA_LIBRARY_MODEL setting, the media library does not appear in the admin.

Or use the built-in models​

The content_studio.media_library app ships media item and folder models that follow these rules, with migrations. Add the app and point the settings at its models:

# mysite/settings.py
INSTALLED_APPS = [
# ...
"content_studio",
"content_studio.media_library",
]

CONTENT_STUDIO = {
"MEDIA_LIBRARY_MODEL": "content_studio.media_library.models.Media",
"MEDIA_LIBRARY_FOLDER_MODEL": "content_studio.media_library.models.Folder",
}

Working in the media library​

Editors upload files with the upload button or by dragging them onto the library, and add tags in the same step when the model has a tags field. They move files between folders, edit their details, and copy or download a file from its menu.

The library has three views: a grid of thumbnails, a list and a table with sortable columns for name, type and size. The admin remembers the view, the filters and the sort order per media model. The search and the current folder are part of the URL, so a filtered view survives a reload and the back button.

The search matches names and tags. Two filters narrow the items further:

  • Type: image, video, audio or file.
  • Tags: any of the selected tags.

With folders, the search covers the current folder or the whole library, set with the toggle next to the search box. Each folder shows how many items it holds.

Select items to delete them or move them to another folder. Deleting needs the model's delete permission, moving its change permission.

Uploads​

The media library accepts the file types in MEDIA_LIBRARY_ALLOWED_EXTENSIONS, up to MEDIA_LIBRARY_MAX_UPLOAD_SIZE (50 MB by default). It rejects files whose content is markup, such as HTML or SVG: served from your own domain, such a file could run scripts in your editors' sessions.

Customize with site hooks​

Three methods on the site change how the media library behaves. Add them to your site subclass:

# mysite/studio.py
from content_studio.admin import ContentStudioSite


class BlogStudioSite(ContentStudioSite):
def get_thumbnail(self, obj):
return obj.thumbnail.url if obj.thumbnail else obj.file.url

def get_media_serializer_fields(self, media_model):
return ["id", "name", "type", "tags", "file", "folder"]

def crop_image(self, obj, crop_info):
# Crop obj's file the way your project needs.
...


admin_site = BlogStudioSite()
  • get_thumbnail(obj) returns the thumbnail URL of an image. By default, the file's own URL.
  • get_media_serializer_fields(media_model) returns the fields of a media item the admin works with. By default, all fields; leave out fields editors should not see.
  • crop_image(obj, crop_info) turns on cropping (see below).

Cropping and focal points​

Cropping appears once the site defines crop_image. When an editor saves a crop selection, the admin passes it to the method as percentages of the image:

{"x": "10.00", "y": "20.00", "width": "50.00", "height": "40.00", "unit": "%"}

What a crop does is up to your method: create a derivative, resize the file in place or store the selection. The edit page then shows the updated item.

A focal point is stored on the item itself. Name its JSONField in FOCAL_POINT_ATTR and editors can click the image to set it; it is saved as {"x": 0-100, "y": 0-100}, percentages of the image's width and height.