Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .annotation_safe_list.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ auth.User:
".. pii_retirement": "consumer_api"
contenttypes.ContentType:
".. no_pii:": "This model has no PII"
openedx_content.Asset:
".. no_pii:": "This model has no PII"
openedx_content.AssetBundle:
".. no_pii:": "This model has no PII"
openedx_content.AssetBundleType:
".. no_pii:": "This model has no PII"
openedx_content.AssetBundleVersion:
".. no_pii:": "This model has no PII"
openedx_content.AssetBundleVersionAsset:
".. no_pii:": "This model has no PII"
openedx_content.AssetType:
".. no_pii:": "This model has no PII"
openedx_content.AssetVersion:
".. no_pii:": "This model has no PII"
openedx_content.AssetVersionMedia:
".. no_pii:": "This model has no PII"
openedx_content.Collection:
".. no_pii:": "This model has no PII"
openedx_content.CollectionPublishableEntity:
Expand Down
1 change: 1 addition & 0 deletions src/openedx_content/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# `DraftChangeLogEventData` vs `DraftChangeLogRecord` is clearer if the former is `signals.DraftChangeLogEventData`)
from . import signals
# The rest of the public API (other than models):
from .applets.assets.api import *
from .applets.backup_restore.api import *
from .applets.collections.api import *
from .applets.components.api import *
Expand Down
Empty file.
155 changes: 155 additions & 0 deletions src/openedx_content/applets/assets/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
"""
Django admin for the assets applet.

Unlike Container subclasses (which are browsable through the generic Container
admin), Asset and AssetBundle are standalone PublishableEntities, so they each
get their own read-only admin here.
"""
from django.contrib import admin
from django.template.defaultfilters import filesizeformat

from openedx_django_lib.admin_utils import ReadOnlyModelAdmin, model_detail_link

from .models import Asset, AssetBundle, AssetBundleType, AssetBundleVersion, AssetType, AssetVersion


@admin.register(AssetType)
class AssetTypeAdmin(ReadOnlyModelAdmin):
"""Read-only admin for AssetType."""

list_display = ("code",)
search_fields = ("code",)


@admin.register(AssetBundleType)
class AssetBundleTypeAdmin(ReadOnlyModelAdmin):
"""Read-only admin for AssetBundleType."""

list_display = ("code",)
search_fields = ("code",)


class AssetVersionInline(admin.TabularInline):
"""Inline view of AssetVersions from the Asset admin."""

model = AssetVersion
fields = ["version_num", "title", "uuid", "created"]
readonly_fields = fields # type: ignore[assignment]
extra = 0

def get_queryset(self, request):
return super().get_queryset(request).select_related("publishable_entity_version")


@admin.register(Asset)
class AssetAdmin(ReadOnlyModelAdmin):
"""Read-only admin for Asset."""

list_display = ("asset_code", "asset_type", "uuid", "created")
readonly_fields = ["learning_package", "asset_type", "asset_code", "uuid", "created"]
list_filter = ("asset_type", "learning_package")
search_fields = ["asset_code", "publishable_entity__uuid", "publishable_entity__entity_ref"]
inlines = [AssetVersionInline]

def get_queryset(self, request):
return super().get_queryset(request).select_related(
"asset_type",
"publishable_entity",
"publishable_entity__learning_package",
)


class AssetVersionMediaInline(admin.TabularInline):
"""Inline view of the Media variants attached to an AssetVersion."""

model = AssetVersion.media.through
fields = ["variant", "media", "format_size"]
readonly_fields = fields # type: ignore[assignment]
extra = 0

def get_queryset(self, request):
return super().get_queryset(request).select_related("media", "media__media_type")

@admin.display(description="Size")
def format_size(self, avm_obj):
return filesizeformat(avm_obj.media.size)


@admin.register(AssetVersion)
class AssetVersionAdmin(ReadOnlyModelAdmin):
"""Read-only admin for AssetVersion."""

list_display = ["asset", "version_num", "uuid", "created"]
fields = ["asset", "uuid", "title", "version_num", "created"]
readonly_fields = fields # type: ignore[assignment]
inlines = [AssetVersionMediaInline]

def get_queryset(self, request):
return super().get_queryset(request).select_related(
"asset",
"asset__publishable_entity",
"publishable_entity_version",
)


class AssetBundleVersionInline(admin.TabularInline):
"""Inline view of AssetBundleVersions from the AssetBundle admin."""

model = AssetBundleVersion
fields = ["version_num", "title", "uuid", "created"]
readonly_fields = fields # type: ignore[assignment]
extra = 0

def get_queryset(self, request):
return super().get_queryset(request).select_related("publishable_entity_version")


@admin.register(AssetBundle)
class AssetBundleAdmin(ReadOnlyModelAdmin):
"""Read-only admin for AssetBundle."""

list_display = ("bundle_code", "asset_bundle_type", "uuid", "created")
readonly_fields = ["learning_package", "asset_bundle_type", "bundle_code", "uuid", "created"]
list_filter = ("asset_bundle_type", "learning_package")
search_fields = ["bundle_code", "publishable_entity__uuid", "publishable_entity__entity_ref"]
inlines = [AssetBundleVersionInline]

def get_queryset(self, request):
return super().get_queryset(request).select_related(
"asset_bundle_type",
"publishable_entity",
"publishable_entity__learning_package",
)


class AssetBundleVersionAssetInline(admin.TabularInline):
"""Inline view of the member Assets of an AssetBundleVersion."""

model = AssetBundleVersion.assets.through
fields = ["asset_link"]
readonly_fields = fields # type: ignore[assignment]
extra = 0

def get_queryset(self, request):
return super().get_queryset(request).select_related("asset", "asset__asset_type")

@admin.display(description="Asset")
def asset_link(self, abva_obj):
return model_detail_link(abva_obj.asset, str(abva_obj.asset))


@admin.register(AssetBundleVersion)
class AssetBundleVersionAdmin(ReadOnlyModelAdmin):
"""Read-only admin for AssetBundleVersion."""

list_display = ["asset_bundle", "version_num", "uuid", "created"]
fields = ["asset_bundle", "uuid", "title", "version_num", "created"]
readonly_fields = fields # type: ignore[assignment]
inlines = [AssetBundleVersionAssetInline]

def get_queryset(self, request):
return super().get_queryset(request).select_related(
"asset_bundle",
"asset_bundle__publishable_entity",
"publishable_entity_version",
)
Loading
Loading