Как мне обслуживать медиафайлы в локальной среде Django?

Я могу загрузить изображение через страницу администратора, но изображение не может быть найдено, когда я перехожу по URL-адресу, сгенерированному django. (ошибка 404) Файлы загружаются в папку:

project_root/media/eventbanner/1/

Я пробовал несколько решений, но ни одно из них не работает в моей ситуации. Django 1.10 запускается локально на Ubuntu 16.04.

URL-адрес, который я получаю:

http://localhost:8000/media/eventbanner/1/banner_image.jpg

Корневая папка мультимедиа находится по адресу:

/home/username/xxx/xxx/project_name/media

Код в HTML-файле:

<div class="banner-image">
  <img src="{{ event.eventbanner.banner_image.url }}"/>
</div>

код url.py:

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

app_name = 'events'

urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^details/(?P<event_id>[0-9]+)/$', views.details, name='details'),
url(r'^details/(?P<event_id>[0-9]+)/addcomment/$', views.add_comment, name='add_comment'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

settings.py

STATIC_URL = '/static/'
STATICFILES_DIRS =[os.path.join(BASE_DIR, 'static'),]

MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'

модели.py

def validate_only_one_instance(obj):
    model = obj.__class__
    if (model.objects.count() > 0 and obj.id != model.objects.get().id):
        raise ValidationError("Can only create 1 %s instance" % model.__name__)

class EventBanner(models.Model):
    event = models.OneToOneField(Event, unique=True)
    banner_image = models.ImageField(upload_to=get_image_path, blank=True, null=True)

    def clean(self):
        validate_only_one_instance(self)

person MarkerDave    schedule 04.01.2017    source источник
comment
Для информации, это стало намного проще с Django 2.0+: docs.djangoproject.com /ru/2.1/ref/urls/#static   -  person Nielk    schedule 18.01.2019


Ответы (2)


Настоящая проблема заключается в том, что между этим URL-адресом http://localhost:8000/media/eventbanner/1/banner_image.jpg и этим местоположением на диске /home/username/xxx/xxx/project_name/media нет никакой связи.

В рабочем приложении у вас будет веб-сервер, на котором вы будете хранить свой Media контент, URL-адрес обслуживания будет MEDIA_ROOT, и вы должны добавить ImageField.url к этому значению, чтобы получить действительный путь к изображению.

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

Обслуживание файлов в разработке

Вам нужно выполнить некоторую работу, чтобы медиафайлы обслуживались локально. Это требует некоторых изменений в вашем urls.py ...

from django.conf import settings
from django.views.static import serve

# ... the rest of your URLconf goes here ...

if settings.DEBUG:
    urlpatterns += [
        url(r'^media/(?P<path>.*)$', serve, {
            'document_root': settings.MEDIA_ROOT,
        }),
    ]

Это использует бит views.serve и должно использоваться только в режиме DEBUG. Он переопределяет путь к медиафайлам (термин django для загруженного пользователем контента, например ImageField). Это перенаправит эти запросы через представление serve. Лучшее, что я могу сказать, это мини-веб-сервер, который сопоставляет эти маршруты запросов с местоположениями на диске и позволяет этим местоположениям быть доступными через URL-адреса HTTP.

person nsfyn55    schedule 04.01.2017

По крайней мере, в Django 1.8 существует вспомогательная функция static(), которая настроит это для вас и обеспечит работу только в режиме отладки.

Ваш urls.py должен выглядеть примерно так:

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

...просто процитировать документацию.

Убедитесь, что для вашего MEDIA_URL задан относительный путь, такой как /media/, и что ваш MEDIA_ROOT является абсолютным путем файловой системы, таким как /home/foo/project/media.

person HorsePunchKid    schedule 31.01.2020