From 0c59bc5e772745045f3aa0021ed53deb04c2675a Mon Sep 17 00:00:00 2001 From: Viner Abubakirov Date: Fri, 2 Jan 2026 03:05:53 +0500 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D1=8B=20=D0=B0=D0=B4?= =?UTF-8?q?=D0=BC=D0=B8=D0=BD=D0=BA=D0=B8=20"=D0=90=D1=80=D1=82=D0=B8?= =?UTF-8?q?=D1=81=D1=82"=20=D0=B8=20"=D0=90=D0=BB=D1=8C=D0=B1=D0=BE=D0=BC"?= =?UTF-8?q?,=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B8=D0=BB=20=D0=BB=D0=B8=D1=88?= =?UTF-8?q?=D0=BD=D0=B5=D0=B5=20=D0=BF=D0=BE=D0=BB=D0=B5=20=D0=B2=20=D0=BC?= =?UTF-8?q?=D0=BE=D0=B4=D0=B5=D0=BB=D0=B8=20"=D0=90=D0=BB=D1=8C=D0=B1?= =?UTF-8?q?=D0=BE=D0=BC"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- music_storage/music/admin.py | 66 +++++++++++++++++-- .../migrations/0002_remove_track_artist.py | 17 +++++ music_storage/music/models.py | 3 +- music_storage/music/views.py | 2 +- music_storage/templates/music/track_list.html | 2 +- 5 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 music_storage/music/migrations/0002_remove_track_artist.py diff --git a/music_storage/music/admin.py b/music_storage/music/admin.py index 2378241..ecd9572 100644 --- a/music_storage/music/admin.py +++ b/music_storage/music/admin.py @@ -1,4 +1,9 @@ +from typing import Any + from django.contrib import admin +from django.http import HttpRequest +from django.urls import reverse +from django.utils.html import format_html from music.models import Track, Album, Artist @@ -6,14 +11,26 @@ from music.models import Track, Album, Artist @admin.register(Track) class TrackAdmin(admin.ModelAdmin): class Media: - js = ('admin/js/upload_progress.js',) - css = { - 'all': ('admin/css/upload_progress.css',) - } + js = ("admin/js/upload_progress.js",) + css = {"all": ("admin/css/upload_progress.css",)} - list_display = ("artist__name", "title", "created_by", "created_at") - search_fields = ("title", "artist__name", "album__name") - list_filter = ("artist__name",) + list_display = ("album__artist__name", "title", "created_by", "created_at") + search_fields = ("title", "album__artist__name", "album__name") + list_filter = ("album__artist__name",) + + +class TrackInline(admin.TabularInline): + model = Track + extra = 1 + show_change_link = True + + def has_change_permission( + self, request: HttpRequest, obj: Any | None = None + ) -> bool: + return False + + def has_add_permission(self, request: HttpRequest, obj: Any | None = None) -> bool: + return False @admin.register(Album) @@ -21,9 +38,44 @@ class AlbumAdmin(admin.ModelAdmin): list_display = ("artist__name", "name") search_fields = ("artist__name", "name") list_filter = ("artist__name",) + inlines = [TrackInline] + readonly_fields = ("add_music_track_link",) + + def add_music_track_link(self, obj: Any | None) -> str: + if obj is None or not obj.pk: + return "" + url = reverse("admin:music_track_add") + f"?album={obj.pk}" + return format_html('Add Music Track', url) + + add_music_track_link.short_description = "Add Music Track" + + +class AlbumInline(admin.TabularInline): + model = Album + extra = 1 + fields = ("name",) + show_change_link = True + + def has_change_permission( + self, request: HttpRequest, obj: Any | None = None + ) -> bool: + return False + + def has_add_permission(self, request: HttpRequest, obj: Any | None = None) -> bool: + return False @admin.register(Artist) class ArtistAdmin(admin.ModelAdmin): list_display = ("name",) search_fields = ("name",) + inlines = [AlbumInline] + readonly_fields = ("add_album_link",) + + def add_album_link(self, obj: Any | None) -> str: + if obj is None or not obj.pk: + return "" + url = reverse("admin:music_album_add") + f"?artist={obj.pk}" + return format_html('Add Album', url) + + add_album_link.short_description = "Add Album" diff --git a/music_storage/music/migrations/0002_remove_track_artist.py b/music_storage/music/migrations/0002_remove_track_artist.py new file mode 100644 index 0000000..c6245e8 --- /dev/null +++ b/music_storage/music/migrations/0002_remove_track_artist.py @@ -0,0 +1,17 @@ +# Generated by Django 6.0 on 2026-01-01 21:05 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('music', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='track', + name='artist', + ), + ] diff --git a/music_storage/music/models.py b/music_storage/music/models.py index ec1d6c7..90b4863 100644 --- a/music_storage/music/models.py +++ b/music_storage/music/models.py @@ -19,9 +19,8 @@ class Album(BaseModel): class Track(BaseModel): title = models.CharField(max_length=200) - artist = models.ForeignKey(Artist, on_delete=models.CASCADE) album = models.ForeignKey(Album, blank=True, null=True, default=None, on_delete=models.SET_DEFAULT) file = models.FileField(upload_to="music/") def __str__(self): - return f"{self.artist} - {self.title}" + return f"{self.album.artist} - {self.title}" diff --git a/music_storage/music/views.py b/music_storage/music/views.py index 838d1fd..f0d4d95 100644 --- a/music_storage/music/views.py +++ b/music_storage/music/views.py @@ -10,7 +10,7 @@ from music.models import Album class TrackListView(django_views.View): def get(self, request: HttpRequest, *args, **kwargs): - tracks = Track.objects.all() + tracks = Track.objects.all().select_related("album__artist",) return render(request, "music/track_list.html", {"tracks": tracks}) diff --git a/music_storage/templates/music/track_list.html b/music_storage/templates/music/track_list.html index e86b537..ab67c4e 100644 --- a/music_storage/templates/music/track_list.html +++ b/music_storage/templates/music/track_list.html @@ -295,7 +295,7 @@
  • {{ track.title }}

    -

    Исполнитель: {{ track.artist }}

    +

    Исполнитель: {{ track.album.artist }}

  • {% endfor %}