Визуализация загруженных изображений в Django Admin

Хотя я нашел полезные посты о том, как правильно отображать изображения в Django-Admin ( # 1, # 2, # 3), я до сих пор не добился успеха, следуя хорошим советам. Как вы можете видеть ниже, загруженные изображения не отображаются должным образом и отображается ошибка 404.

Рисунок ниже иллюстрирует тот факт, что загруженные изображения не отображаются, хотя они были успешно загружены на сервер: Неработающие ссылки на загруженные изображения

Когда я щелкаю мышью по неработающей ссылке, в браузере отображается следующая ошибка: Ошибка URL

При редактировании данного объекта мне также было интересно, как отобразить миниатюру, а не путь к изображению: URL к изображению Ниже вы можете найти конфигурацию, которую я использовал до сих пор:

settings.py

import os
PROJECT_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..').replace('\\','/')
SITE_ROOT = PROJECT_ROOT

# Path to media files, e.g. images
MEDIA_ROOT = os.path.join(SITE_ROOT, 'media')
MEDIA_URL = '/media/'

urls.py

from django.conf.urls import patterns, include, url
from django.conf.urls.static import static
from django.conf import settings
from . import views

urlpatterns = patterns('',
    # some url configs here ... removed for simplification purposes ;-)
)

if settings.DEBUG is True:
    urlpatterns += patterns('', (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}) )
    #urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

models.py

class Image(models.Model):
    title = models.CharField(db_column='title', max_length=180, blank=True, null=True, help_text="Title of the image") 
    imagefile = models.ImageField(db_column='imagefile', upload_to='images', null=True, blank=True, help_text="Load an image.")
    #... some other fields here, removed for simplification purposes ;-)

    def image_(self):
        return '<a href="/media/{0}"><img src="/media/{0}"></a>'.format(self.imagefile)
    image_.allow_tags = True

    class Meta:
        managed = False
        db_table = 'image'

    def __unicode__(self):
        return u'%s' % (self.title)

admin.py

from django.contrib import admin
from .models import Image

class ImageAdmin(admin.ModelAdmin):
    list_display = ('title', 'description', 'image_', )
    search_fields = ('title', 'description')
    list_per_page = 25

admin.site.register(Image, ImageAdmin)

4 ответа

Этот ответ откладывается как минимум на один год, но, тем не менее, если у вас все еще остается та же проблема, вы можете исправить ее следующим образом:

Прежде всего, давайте предположим, что у вашего проекта django есть эта архитектура, и вы используете django 2.0:

. django_test
|_ django_test
|  |_ __init__.py
|  |_ settings.py
|  |_ urls.py
|  |_ wsgi.py
|_ media
|  |_ author_headshot
|_ my_app
|  |_ admin.py
|  |_ __init__.py
|  |_ apps.py
|  |_ migrations
|  |_ models.py
|  |_ tests.py
|  |_ urls.py
|  |_ views.py
|_ static
|_ templates

Затем добавьте в свой django_test / settings.py:

# static files will be stored in 'static' folder
STATIC_URL = '/static/'
STATICFILES_DIR = [
    BASE_DIR + '/static'
]
# media files will be stored in 'media' folder
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR + '/media'

Затем в django_test/urls.py обязательно добавьте статический путь к вашим MEDIA_URL и MEDIA_ROOT, как в этом примере:

from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
    # More paths/urls
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

И, наконец, в вашей модели приложения вы можете добавить уникальную папку для каждого ImageField, где будут храниться ваши медиа-файлы, как в следующем примере:

В my_app / models.py:

from django.db import models
from django.utils.html import format_html

class Author(models.Model):
    # My models ...
    # Here, the media files will be stored in my_project/media/author_headshot
    headshot = models.ImageField(upload_to='author_headshot')

    # If you want to show the media files in the list display in the admin panel:
    def image_tag(self):
        return format_html('<img href="{0}" src="{0}" width="150" height="150" />'.format(self.headshot.url))

    image_tag.allow_tags = True
    image_tag.short_description = 'Image'

Затем в my_app / admin.py:

from django.contrib import admin
from . import models

@admin.register(models.Author)
class AuthorAdmin(admin.ModelAdmin):
    list_display = ('image_tag')

Наконец, ваши медиа-файлы будут иметь такие URL-адреса:

http://example.domain/media/file_path.extension

Скриншоты админ-панели django:

Вы пробовали что-то вроде этого:

admin.py

from django.contrib import admin
from .models import Image

class ImageAdmin(admin.ModelAdmin):
    list_display = ('title', 'description', 'image_display', )
    search_fields = ('title', 'description')
    list_per_page = 25

    def image_display(self, obj):
        return '<a href="/media/{0}"><img src="/media/{0}"></a>'.format(self.imagefile.url)
    image_.allow_tags = True
    image.short_descripition = u'IMAGE'

admin.site.register(Image, ImageAdmin)

Это всегда работает для меня. Дайте мне знать, если это помогло.

Есть тонкая линия, когда вы используете ImageField и когда вы используете функцию image_(self), чтобы сделать изображение видимым. См. Диаграмму ниже: это ссылка на изображение, так как моя репутация не позволяет мне публиковать изображения. Столбец img1 представляет переменную imagefile, которую вы использовали в models.py.


Изображения ImageField сохраняются в папке images, которая является каталогом your-project / media / images.


Ваша функция image_(self) указывает на один уровень глубже, когда вы используете "media / {0}", т.е. она будет указывать на ваш проект / media // media / images (обратите внимание на // здесь, который прибывает из-за дополнительных / из / {0}). Ваши функции должны быть изменены следующим образом:


def image_tag(self):
    return '<a href="{0}"><img src="{0}" width = "120" height = "120"></a>'.format(self.img1.url)
image_tag.allow_tags = True
image_tag.short_description = 'y-Image'

Если вы являетесь пользователем Chrome, попробуйте расширение «Веб-сервер для Chrome», которое вы можете найти здесь: /questions/25894783/ne-udaetsya-otkryit-lokalnyij-fajl-chrome-zaprescheno-zagruzhat-lokalnyij-resurs/25894794#25894794

Chrome блокирует локальные ресурсы, поэтому это расширение заставляет его «думать», что загружает онлайн-ресурс.

Убедитесь, что ваш srcначинается с «http://», например:

      def display_image(self):
    return format_html(
        "<img src='http://127.0.0.1/8887{}'>", 
        self.image_attribute.url
)
Другие вопросы по тегам