Django медиа url из модели
Я работаю над простым блогом, у меня есть такая модель для записи в блоге:
class BlogPost(models.Model):
title = models.CharField(max_length=150, unique=True)
body = models.TextField()
cover_image = models.ImageField(upload_to='blogposts/')
created_on = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
category = models.ManyToManyField('PostCategory', related_name='posts')
slug = models.SlugField(null=True, unique=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("blog_detail", kwargs={"slug": self.slug})
В файле настроек у меня следующая конфигурация для статических и медиа файлов:
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Я создаю модели и представления блога в отдельном приложении, которое я назвал "blog"
Я использую Django classed-based list view для отображения постов на странице:
class BlogListView(ListView):
model = BlogPost
template_name = "blog/blog_list.html"
И у меня URL файлы работают просто отлично: Проблема заключается в отображении его в моем представлении шаблона, в основном для изображения обложки поста:
{% for post in object_list %}
<!-- Single Blog Item -->
<div class="single-blog-item style-2 d-flex flex-wrap align-items-center mb-50">
<!-- Blog Thumbnail -->
<div class="blog-thumbnail">
<a href="{{ post.get_absolute_url }}">
<img src="{{ post.cover_image }}" alt="">
</a>
</div>
<!-- Blog Content -->
<div class="blog-content">
<a href="{{ post.get_absolute_url }}" class="post-title">{{ post.title }}</a>
<p>We'll come back to this...</p>
<div class="post-meta">
<a href="#"><i class="icon_clock_alt"></i> {{ post.created_on }}</a>
<a href="#"><i class="icon_chat_alt"></i> 3 Comments</a>
</div>
</div>
</div>
{% endfor %}
Все остальные теги работают нормально, кроме изображения обложки. Тег шаблона {{ post.cover_image }} не отображает никакого изображения, после осмотра страницы для одного из постов я обнаружил, что он ссылается на:
http://127.0.0.1:8000/blog/blogpost/12.png
страницы выше не существует, изображение действительно было загружено в папку media. Следовательно, загруженное изображение из модели находится здесь:
http://127.0.0.1:8000/blog/blogpost/12.png
но тег {{ post.cover_image }} ссылается на несуществующую страницу ниже:
http://127.0.0.1:8000/blog/blogpost/12.png
Как решить эту проблему, чтобы тег ссылки на нужное место отображал правильный URL изображения?
from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls')),
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Я понял ответ из комментария Ивана;
Использование {{ post.cover_image }} не отображает URL изображения (или медиафайла) в целом, оно отображает только имя файла и расположение в корне медиафайла.
Отсюда,
{{ post.cover_image }} = blogposts/12.png
, который автоматически соединяется с URL страницы блога для создания несуществующей ссылки для изображения, показанного в сообщении. Однако,
{{ post.cover_image.url }}
исправляет это, с добавлением .url, он рендерит URL медиафайла и отображает его правильно.
Так:
{{ post.cover_image.url }} = http://127.0.0.1:8000/media/blogpost/12.png
Это работает отлично!