如何在Django生产环境中提供媒体文件?

2024-05-20 22:41:55 发布

您现在位置:Python中文网/ 问答频道 /正文

在me settings.py文件中:

DEBUG = False
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

STATIC_URL = '/static/'
LOGIN_URL = '/login/'
MEDIA_URL = '/media/'

在my urls.py文件中:

urlpatterns += static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)

当我上载配置文件图像时,它将上载到指定的文件夹。但是当我访问用户配置文件url时,我在终端中会遇到这样的错误

"GET /media/profile_images/a_34.jpg HTTP/1.1" 404 103

a_34.png出现在/media/profile_images/

那为什么它没有显示在浏览器上,我得到404错误?


Tags: 文件pathpyurlbasesettingsosdir
3条回答

Django不是为生产环境中的媒体文件服务的。必须直接从web服务器配置它。

例如

如果您在生产环境中使用apache web服务器,请将以下内容添加到virtualhost配置中

Alias /media/ /path/to/media_file/

<Directory /path/to/media_file/>
Order deny,allow
Allow from all
</Directory>

如果你使用Nginx,你会有类似的配置。

您可以使用S3 Amazon来处理静态和媒体文件。会更好的。


S3 Amazon的问题

使S3 bucket作为文件系统的一部分出现有糟糕的性能,并且会随机失败。当我们复制大量文件时,可能需要10、15或20分钟的时间才能完成复制,而在不需要时,完成部署需要很长的时间。如果我们直接将它们发送到S3中,相同的copy命令大约需要1分钟才能完成。

解决方案

子类S3BotoStorage两次,一个用于静态文件,另一个用于媒体文件。这允许我们为每种类型使用不同的bucket和子目录。(请参见:custom_storage.py)

更新设置

1. AWS_STORAGE_BUCKET_NAME  needs to be bucket to hold static files and media files
2. MEDIAFILES_BUCKET
3. MEDIAFILES_LOCATION
4.DEFAULT_FILE_STORAGE
5.STATICFILES_BUCKET
6.STATICFILES_LOCATION
This is the subdirectory under the S3 bucket for the app
7.STATIC_URL
8.STATICFILES_STORAGE

创建包含以下内容的自定义存储.py:

from django.utils.deconstruct import deconstructible
from storages.backends.s3boto import S3BotoStorage
from django.conf import settings

@deconstructible
class StaticS3Storage(S3BotoStorage):
   bucket_name = settings.STATICFILES_BUCKET
   location = settings.STATICFILES_LOCATION

@deconstructible
class MediaS3Storage(S3BotoStorage):
   bucket_name = settings.MEDIAFILES_BUCKET
   location = settings.MEDIAFILES_LOCATION

示例settings.py.tmpl用于基于my stack.json的更新设置(如上所述)

MEDIAFILES_BUCKET = '<%= @node["apps_data"]["aws"]["buckets"]["bucket-name"] %>'
MEDIAFILES_LOCATION = 'folder_name_for_media_files_in_bucket'
DEFAULT_FILE_STORAGE = 'custom_storage.MediaS3Storage'

# If we're not using our S3 backend storage we need to serve the media files via path
   if DEFAULT_FILE_STORAGE == "custom_storage.MediaS3Storage":
       MEDIA_URL = 'https://%s.s3-website-us-east-1.amazonaws.com/%s/' %      (MEDIAFILES_BUCKET, MEDIAFILES_LOCATION)
   else:
       MEDIA_URL = '/media/'

   STATICFILES_BUCKET = '<%= @node["apps_data"]["aws"]["buckets"]["bucket-name"] %>'
   STATICFILES_LOCATION = 'folder_name_for_static_files_in_bucket'
   STATICFILES_STORAGE = '<%= @node["deploy_data"]["project_name"]["django_static_files_storage"] %>'

# If we're not using our S3 backend storage we need to serve the static files via path
   if STATICFILES_STORAGE == "custom_storage.StaticS3Storage":
       STATIC_URL = 'https://%s.s3-website-us-east-1.amazonaws.com/%s/' % (STATICFILES_BUCKET, STATICFILES_LOCATION)
   else:
       STATIC_URL = '/static/'

从staticfiles Django Template标记加载static

将模板中{%load static%}的所有用法更改为{%load static from staticfiles%}

静态文件中的“static”可以使用不同的文件后端,包括S3后端或本地文件后端。使用“load static”使用Django模板标记库,它不处理不同的后端。

在包含静态文件以及包含“static from staticfiles”之后的模板中使用此选项: {%static“路径/to/the/file.ext”%} 这将确定文件的完整路径,或者如果它在S3中,它将插入文件的完整URL。

示例

<link rel="stylesheet" type="text/css" href="{% load static from staticfiles %}{% static "css/style.css" %}”>

有用信息

“django.contrib.static files.storage.StaticFilesStorage”是默认的django静态文件后端

参考资料

https://docs.djangoproject.com/en/1.9/howto/static-files/https://www.caktusgroup.com/blog/2014/11/10/Using-Amazon-S3-to-store-your-Django-sites-static-and-media-files/

Django不鼓励从服务器为生产上的媒体文件提供服务。使用类似amazon s3的云服务来为媒体文件提供服务器。请参阅此Django doc serve media,然后在媒体URL中给出该路径。

相关问题 更多 >