Обновил шаблон для album_list.html и добавил функцию для cover_image в модели Album
This commit is contained in:
@@ -1,6 +1,14 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from core.models import BaseModel
|
from core.models import BaseModel
|
||||||
|
|
||||||
|
import os
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
def album_cover_upload_to(instance, filename):
|
||||||
|
ext = filename.split(".")[-1]
|
||||||
|
return os.path.join("album_covers", f"{uuid.uuid4()}.{ext}")
|
||||||
|
|
||||||
|
|
||||||
class Artist(BaseModel):
|
class Artist(BaseModel):
|
||||||
name = models.CharField(max_length=200)
|
name = models.CharField(max_length=200)
|
||||||
@@ -12,7 +20,9 @@ class Artist(BaseModel):
|
|||||||
class Album(BaseModel):
|
class Album(BaseModel):
|
||||||
artist = models.ForeignKey(Artist, on_delete=models.CASCADE, related_name="albums")
|
artist = models.ForeignKey(Artist, on_delete=models.CASCADE, related_name="albums")
|
||||||
name = models.CharField(max_length=200)
|
name = models.CharField(max_length=200)
|
||||||
cover_image = models.ImageField(upload_to="album_covers/", null=True, blank=True)
|
cover_image = models.ImageField(
|
||||||
|
upload_to=album_cover_upload_to, null=True, blank=True
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.artist} - {self.name}"
|
return f"{self.artist} - {self.name}"
|
||||||
|
|||||||
46
music_storage/static/css/album_list.css
Normal file
46
music_storage/static/css/album_list.css
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
.album-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-card {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-card:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-link {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-cover {
|
||||||
|
width: 100%;
|
||||||
|
height: 220px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-info {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-name {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.album-artist {
|
||||||
|
margin: 4px 0 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
@@ -1,11 +1,26 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
|
|
||||||
<ul>
|
<link rel="stylesheet" href="{% static 'css/album_list.css' %}">
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="album-container">
|
||||||
{% for album in albums %}
|
{% for album in albums %}
|
||||||
<li>
|
<div class="album-card">
|
||||||
<a href="{% url 'music:album_detail' album.id %}">{{ album.name }}</a> by {{ album.artist }}
|
<a href="{% url 'music:album_detail' album.id %}" class="album-link">
|
||||||
</li>
|
{% if album.cover_image %}
|
||||||
|
<img src="{{ album.cover_image.url }}" alt="{{ album.name }}" class="album-cover">
|
||||||
|
{% else %}
|
||||||
|
<img src="{% static 'img/no-cover.png' %}" alt="No cover" class="album-cover">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="album-info">
|
||||||
|
<h3 class="album-name">{{ album.name }}</h3>
|
||||||
|
<p class="album-artist">{{ album.artist }}</p>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<li>No albums available.</li>
|
<p>No albums available.</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</div>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user