123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- from django.conf import settings
- from django.contrib import admin
- from django.db.models import Count, F
- from django.urls import reverse
- from django.utils.html import format_html
- from django.utils.translation import gettext as _
- from furl import furl
- from rest_framework.reverse import reverse as drf_reverse
- from .models import Album, Artist, Track
- def get_api_url(obj, view="detail", params=None, title=None, request=None):
- path = drf_reverse(
- f"{obj._meta.model_name}-{view}",
- kwargs={
- "uuid": obj.uuid,
- "version": settings.REST_FRAMEWORK["DEFAULT_VERSION"],
- },
- request=request,
- )
- if params:
- path = furl(path).set(params).url
- return format_html('<a href="{0}" title="{1}">{1}</a>', path, title or str(obj))
- def get_admin_url(obj, view="change", params=None, title=None):
- path = reverse(
- f"admin:{obj._meta.app_label}_{obj._meta.model_name}_{view}",
- kwargs={"object_id": obj.pk} if view == "change" else {},
- )
- if params:
- path = furl(path).set(params).url
- return format_html('<a href="{0}" title="{1}">{1}</a>', path, title or str(obj))
- class ArtistDecadeActiveListFilter(admin.SimpleListFilter):
- title = _("decade active")
- parameter_name = "decade_active"
- def lookups(self, request, model_admin):
- return (
- ("1980", _("1980s")),
- ("1990", _("1990s")),
- ("2000", _("2000s")),
- ("2010", _("2010s")),
- ("2020", _("2020s")),
- )
- def queryset(self, request, queryset):
- try:
- year_since = int(self.value())
- year_until = year_since + 10
- except (TypeError, ValueError):
- return queryset
- return queryset.filter(
- albums__year__gte=year_since, albums__year__lt=year_until
- )
- class ArtistAlbumInline(admin.TabularInline):
- model = Album
- fields = ("name", "year", "album_admin_link", "tracks_admin_link")
- readonly_fields = ("album_admin_link", "tracks_admin_link")
- extra = 0
- def get_queryset(self, request):
- queryset = super().get_queryset(request)
- return queryset.annotate(track_count=Count("tracks"))
- def album_admin_link(self, album):
- return get_admin_url(album)
- album_admin_link.short_description = _("Album")
- def tracks_admin_link(self, album):
- return get_admin_url(
- Track,
- view="changelist",
- params={"album": album.pk},
- title=album.track_count,
- )
- tracks_admin_link.short_description = _("Tracks")
- class AlbumTrackInline(admin.TabularInline):
- model = Track
- fields = ("number", "name")
- extra = 0
- @admin.register(Artist)
- class ArtistAdmin(admin.ModelAdmin):
- list_display = ("name", "albums_admin_link")
- list_filter = (ArtistDecadeActiveListFilter,)
- fields = ("name", "uuid", "albums_admin_link", "artist_api_link")
- readonly_fields = ("uuid", "albums_admin_link", "artist_api_link")
- search_fields = ("uuid", "name")
- inlines = (ArtistAlbumInline,)
- def get_queryset(self, request):
- self.request = request
- queryset = super().get_queryset(request)
- return queryset.prefetch_related("albums").annotate(album_count=Count("albums"))
- def albums_admin_link(self, artist):
- return get_admin_url(
- Album,
- view="changelist",
- params={"artist": artist.pk},
- title=artist.album_count,
- )
- albums_admin_link.short_description = _("Albums")
- albums_admin_link.admin_order_field = "album_count"
- def artist_api_link(self, artist):
- return get_api_url(artist, request=self.request)
- artist_api_link.short_description = _("API")
- @admin.register(Album)
- class AlbumAdmin(admin.ModelAdmin):
- list_display = ("name", "artist_admin_link", "album_year", "tracks_admin_link")
- list_filter = ("year",)
- search_fields = ("uuid", "name", "artist__name")
- fields = (
- "name",
- "year",
- "uuid",
- "artist_admin_link",
- "tracks_admin_link",
- "album_api_link",
- )
- readonly_fields = (
- "uuid",
- "tracks_admin_link",
- "artist_admin_link",
- "album_api_link",
- )
- list_select_related = ("artist",)
- inlines = (AlbumTrackInline,)
- def get_queryset(self, request):
- self.request = request
- queryset = super().get_queryset(request)
- return queryset.annotate(track_count=Count("tracks"))
- def album_year(self, album):
- return get_admin_url(
- Album, view="changelist", params={"year": album.year}, title=album.year
- )
- album_year.short_description = _("Year")
- album_year.admin_order_field = "year"
- def artist_admin_link(self, album):
- return get_admin_url(album.artist)
- artist_admin_link.short_description = _("Artist")
- artist_admin_link.admin_order_field = "artist__name"
- def tracks_admin_link(self, album):
- return get_admin_url(
- Track,
- view="changelist",
- params={"album": album.pk},
- title=album.track_count,
- )
- tracks_admin_link.short_description = _("Tracks")
- tracks_admin_link.admin_order_field = "track_count"
- def album_api_link(self, album):
- return get_api_url(album, request=self.request)
- album_api_link.short_description = _("API")
- @admin.register(Track)
- class TrackAdmin(admin.ModelAdmin):
- list_display = ("name", "artist_admin_link", "album_admin_link", "album_year")
- list_filter = ("album__year",)
- search_fields = ("uuid", "name", "album__name", "album__artist__name")
- fields = (
- "name",
- "uuid",
- "artist_admin_link",
- "album_admin_link",
- "album_year",
- "track_api_link",
- )
- readonly_fields = (
- "uuid",
- "artist_admin_link",
- "album_admin_link",
- "album_year",
- "track_api_link",
- )
- list_select_related = ("album", "album__artist")
- ordering = ("name", "album__artist__name", "album__name")
- def get_queryset(self, request):
- self.request = request
- queryset = super().get_queryset(request)
- return queryset.annotate(album_year=F("album__year"))
- def album_admin_link(self, track):
- return get_admin_url(track.album)
- album_admin_link.short_description = _("Album")
- album_admin_link.admin_order_field = "album__name"
- def artist_admin_link(self, track):
- return get_admin_url(track.album.artist)
- artist_admin_link.short_description = _("Artist")
- artist_admin_link.admin_order_field = "album__artist__name"
- def album_year(self, track):
- return get_admin_url(
- Track,
- view="changelist",
- params={"album__year": track.album_year},
- title=track.album_year,
- )
- album_year.short_description = _("Year")
- album_year.admin_order_field = "album__year"
- def track_api_link(self, track):
- return get_api_url(track, request=self.request)
- track_api_link.short_description = _("API")
|