在 Django 中为生产提供媒体文件

问题描述 投票:0回答:4

我想在 Django 项目中提供所有类型的媒体文件,我使用 Whitenoise 来提供静态文件,并且静态文件运行良好,但在提供用户上传的图像时遇到问题(我正在使用 Linux 共享托管 Cpanel) ) 目录结构

Project_name
App_1
App_2
Staticfiles (that are collected via collectstatic cmd)
manage.py
passenger_wsgi.py

这是项目的settings.py

STATIC_ROOT = BASE_DIR / 'staticfiles'
STATIC_URL = '/static/'
MEDIA_URL = ''
STATICFILES_DIRS =[
    BASE_DIR/ 'static'
]
 MEDIA_ROOT = BASE_DIR / 'staticfiles/images'

和文件 urls.py

urlpatterns+=static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
django django-views django-templates collectstatic whitenoise
4个回答
1
投票

虽然不推荐,但如果您不使用 ngingx/apache 并且服务器较小,则可能需要它。 我的情况是我使用whitenoise 和gunicorn 在本地服务器上提供服务。

您可以通过为媒体文件创建视图来提供媒体文件。

myapp.views.py

def media(request, file_path=None):
    from django.conf import settings as cfg
    media_root = getattr(cfg, 'MEDIA_ROOT', None)

    if not media_root:
        return HttpResponseBadRequest('Invalid Media Root Configuration')
    if not file_path:
        return HttpResponseBadRequest('Invalid File Path')

    with open(os.path.join(media_root, file_path), 'rb') as doc:
        response = HttpResponse(doc.read(), content_type='application/doc')
        response['Content-Disposition'] = 'filename=%s' % (file_path.split('/')[-1])
        return response

现在在应用程序中添加网址

myapp.urls.py

url(r'^myapp/media/(?P<file_path>.+)+', myapp.views.media, name='media'),

settings.py

MEDIA_ROOT = os.path.abspath(__file__ + "../../../media")
MEDIA_URL = '/myapp/media/'

0
投票

Whitenoise 仅在启动时检查静态文件,因此应用程序启动后添加的文件将不会被看到。

因为,Whitenose 不适合提供用户上传的媒体文件。

请查看 Whitenose 官方文档。 http://whitenoise.evans.io/en/latest/django.html#serving-media-files


0
投票

如果您想在生产中从 django 提供媒体服务,只需基于原始静态函数创建您自己的

static
函数,如下所示:

#my_app/static.py

import re
from urllib.parse import urlsplit

from django.core.exceptions import ImproperlyConfigured
from django.urls import re_path
from django.views.static import serve


def static(prefix, view=serve, **kwargs):
    """
    Return a URL pattern for serving files in debug mode.
    from django.conf import settings
    from django.conf.urls.static import static
    urlpatterns = [
        # ... the rest of your URLconf goes here ...
    ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    """
    if not prefix:
        raise ImproperlyConfigured("Empty static prefix not permitted")
    elif urlsplit(prefix).netloc: # <- removed DEBUG from this line
        # No-op if non-local prefix.
        return []
    return [
        re_path(
            r"^%s(?P<path>.*)$" % re.escape(prefix.lstrip("/")), view, kwargs=kwargs
        ),
    ]


0
投票
  1. Whitenoise 仅在启动时检查静态文件,因此应用程序启动后添加的文件将不会被看到。也就是说,只有在静态文件夹中找到的文件才能在静态页面/模板上使用。因此,Whitenose 不得用于提供用户上传的媒体文件。

  2. 要解决此问题,您需要设置一个新的子域来存储图像/媒体文件。例如:

    media.your-domain.com
    。这将在
    public_html
    中创建一个与您的子域同名的目录。这是您必须使用
    django
    以及在提供图像/媒体文件时存储/保存图像/媒体文件的位置(
    by Apache server
    不再是
    django
    )。

  3. 编辑

    settings.py
    (位于 django 项目目录中)以通知 django 在哪里上传媒体文件。

    MEDIA_ROOT = "/home/username/public_html/media.your-domain.com"

    将用户名替换为

    CPanel
    media.your-domain.com
    中的用户名 通过您创建的子域。

    还将

    MEDIA_URL
    变量/常量设置/更改为:

    MEDIA_URL = 'https://media.your-domain.com'

    请记住将上面的地址更改为您创建的子域。经过 这样,

    django
    将不再服务器媒体文件/图像,因为将发送请求 到子域并由
    Apache
    在您的情况下处理。

  4. 在包含媒体文件的目录中创建一个名为

    .haccess
    的文件,这是带有子域名的文件夹,位于 public_html 中。

    编辑文件并添加以下内容:

    <IfModule mod_headers.c> Header set Access-Control-Allow-Origin "https://your-domain.com" </IfModule>

    最后,通过添加以下内容来保护子域以防止目录列出 以下在同一文件中。

    Options All -Indexes

© www.soinside.com 2019 - 2024. All rights reserved.