如何在本地Django环境中提供媒体文件?

Mar*_*ave 8 python django django-staticfiles

我可以通过管理页面上传图像,但是当我导航到django生成的网址时,无法找到图像.(404错误)文件正在上传到文件夹:

project_root/media/eventbanner/1/
Run Code Online (Sandbox Code Playgroud)

我尝试了多种解决方案,但似乎没有一种方法适用于我的情况.Django 1.10正在Ubuntu 16.04上运行.

我得到的网址是:

http://localhost:8000/media/eventbanner/1/banner_image.jpg
Run Code Online (Sandbox Code Playgroud)

媒体根文件夹位于:

/home/username/xxx/xxx/project_name/media
Run Code Online (Sandbox Code Playgroud)

HTML文件中的代码:

<div class="banner-image">
  <img src="{{ event.eventbanner.banner_image.url }}"/>
</div>
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

settings.py

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

MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'
Run Code Online (Sandbox Code Playgroud)

models.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)
Run Code Online (Sandbox Code Playgroud)

nsf*_*n55 18

这里真正的问题是这个url http://localhost:8000/media/eventbanner/1/banner_image.jpg和磁盘上的这个位置之间没有关系/home/username/xxx/xxx/project_name/media.

在生产应用程序中,您将拥有一个Web服务器,您可以在其中存储Media内容,服务URL将被MEDIA_ROOT添加ImageField.url到此值以获取有效的图像路径.

您需要的是为媒体图像设置Web服务器.起初这听起来像很多工作,但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,
        }),
    ]
Run Code Online (Sandbox Code Playgroud)

这使用该views.serve位,只应在DEBUG模式下使用.它覆盖了媒体文件的路径(django用户上传内容的术语ImageField).这将通过serve视图重定向这些请求.最好我可以告诉这是一个迷你Web服务器,它将这些请求路由映射到磁盘上的位置,并允许通过HTTP URL访问这些位置.

  • 将其添加到ROOT urls.py即可达到目的。谢谢。 (2认同)

Hor*_*Kid 7

至少从 Django 1.8 开始,有一个辅助函数 static()可以为您设置并确保它仅在调试模式下运行。

urls.py应该看起来像这样:

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

...简单地引用文档。

确保您MEDIA_URL的设置为相对路径/media/MEDIA_ROOT例如/home/foo/project/media.