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



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

在我的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不是用来在生产环境中提供媒体文件的。必须配置STATIC_ROOT设置和别名webserver直接服务。

例如

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

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

如果你使用Nginx,你必须使用像

这样的东西
location /media {
    alias /path/to/media/file; # Change to your own media directory here.
    access_log off;
}
或者,您也可以使用django-storage

从AWS S3或其他云服务器提供静态文件。

Django不鼓励从服务器端向生产端提供媒体文件。使用像amazon s3这样的云服务来为你的媒体文件提供服务器。请参阅Django文档serve media,然后在MEDIA_URL中给出该路径。

您可以使用S3 Amazon存储静态文件和媒体文件。会更好的。


S3 Amazon的问题

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

<

解决方案/strong>

子类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

<

样本strong> 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/'

Django模板标签

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

来自静态文件的"static"可以使用不同的文件后端,包括S3后端或本地文件后端。使用" load static "使用的是Django模板标签库,它不能处理不同的后端。

在模板中包含静态文件时,以及在包含" static from staticfiles "之后使用:{% static "路径/到/文件。ext " %}这将找出文件的完整路径,或者如果它在S3中,它将插入一个完整的URL到文件。

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

有用信息/strong>

" 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设置:

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 = [
       .........
       .........
    
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

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

最新更新