【问题标题】:How do I serve media files in a local Django environment?如何在本地 Django 环境中提供媒体文件?
【发布时间】:2017-05-18 15:38:59
【问题描述】:

我可以通过管理页面上传图片,但是当我导航到 django 生成的 url 时找不到图片。 (404 错误) 文件正在上传到文件夹:

project_root/media/eventbanner/1/

我尝试了多种解决方案,但似乎没有一个适合我的情况。 Django 1.10 正在 Ubuntu 16.04 上本地运行。

我得到的网址是:

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/'

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)

【问题讨论】:

标签: python django django-staticfiles


【解决方案1】:

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

在生产应用程序中,您将拥有一个 Web 服务器,您将在其中存储您的 Media 内容,服务 URL 将是 MEDIA_ROOT,并且您将在此值后面附加 ImageField.url 以获得有效的图像路径.

您需要在这里为您的媒体图像设置一个网络服务器。一开始听起来工作量很大,但 Django 提供了一个捷径……

Serving Files in Development

您需要做一些工作才能在本地提供媒体文件。它需要对您的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 视图重定向这些请求。我可以说这是一个迷你 Web 服务器,它将这些请求路由映射到磁盘上的位置,并允许通过 HTTP url 访问这些位置。

【讨论】:

    【解决方案2】:

    至少从 Django 1.8 开始,有一个 helper function 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 这样的绝对文件系统路径。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-29
      • 1970-01-01
      • 2021-11-06
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-07
      相关资源
      最近更新 更多