繁体   English   中英

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

[英]How to serve media files on Django production environment?

在我的 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/'

在我的 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 错误?

Django 不是用来在生产环境中提供媒体文件的。 您必须直接从 Web 服务器对其进行配置。

例如

如果您在生产中使用 apache web 服务器,请将以下内容添加到您的虚拟主机配置中

Alias /media/ /path/to/media_file/

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

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

Django 不鼓励从服务器提供媒体文件。 使用 amazon s3 等云服务来管理您的媒体文件。 请参阅此Django 文档服务媒体,然后在 MEDIA_URL 中提供该路径。

您可以将 S3 Amazon 用于静态和媒体文件。 会更好。


S3 亚马逊的问题

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

解决方案

将 S3BotoStorage 子类化两次,一类用于静态文件,另一类用于媒体文件。 这允许我们为每种类型使用不同的存储桶和子目录。 (参见: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

使用以下内容创建custom_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

根据我stack.json样品settings.py.tmpl更新设置(如上所述)

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

从静态文件中加载静态 Django 模板标签

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

静态文件中的“静态”可以为文件使用不同的后端,包括 S3 后端或本地文件后端。 使用“加载静态”使用不处理不同后端的 Django 模板标签库。

在包含静态文件时以及在包含“static from staticfiles”之后在模板中使用它: {% static “path/to/the/file.ext” %} 这将找出文件的完整路径,或者它是否在 S3 中它将插入文件的完整 URL。

示例

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

有用信息

“django.contrib.staticfiles.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/

对于 nginx,它适用于我的以下配置行:

location /media {
    alias /home/ubuntu/speedy-net/media; # Change to your own media directory here.
    access_log off;
}

另请参阅关于代码审查的相关问题

您需要设置一个服务器来在生产中提供静态内容。 当只有 Debug 为 True 时,静态内容由 Django 提供。 所以你需要

1)设置服务器

2) 将服务器媒体路径指向 STATIC_ROOT 目录

3)运行django的collectstatic命令将所有静态文件收集到STATIC_ROOT。 请参考

https://docs.djangoproject.com/en/1.10/howto/static-files/

以下方法对我有用:

我在 Apache 配置文件中添加了以下配置:

alias /media/ /path/to/media/
<Directory /alchemus/django/WebForm/media>
   Require all granted
</Directory>

settings.py文件包含以下媒体设置:

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

确保您在urls.py有以下设置:

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL,
                          document_root=settings.MEDIA_ROOT)

上面的设置是为了确保 django 服务器只在开发过程中提供媒体文件,在生产中提供媒体文件应该由 Apache 服务器处理。

参考资料: https : //docs.djangoproject.com/en/3.2/howto/deployment/wsgi/modwsgi/#serving-files

只需在 urls.py 中添加此代码

urlpatterns = […………

   .........

] + 静态(settings.STATIC_URL,document_root=settings.STATIC_ROOT)

urlpatterns += 静态(settings.MEDIA_URL,document_root = settings.MEDIA_ROOT)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM