简体   繁体   English

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

[英]How To Serve media Files In Production

I have a Django project which sends automated e-mails with attached pdfs to users.我有一个 Django 项目,它向用户发送带有附加 pdf 的自动电子邮件。 At the moment I just have a normal /media/ folder with the pdf in it which the code points to.目前,我只有一个普通的/media/文件夹,其中包含代码指向的 pdf。 This works in development but throws a server error in production.这在开发中有效,但在生产中引发服务器错误。

My question is how do I server media files in production?我的问题是如何在生产中提供media文件? I have read a lot about it but can't find exactly what I'm after.我已经阅读了很多关于它的内容,但找不到我想要的确切内容。

I use collectstatic in my production environment which works for static files, I'd expect something similar for media files.我在我的生产环境中使用collectstatic用于静态文件,我希望media文件有类似的东西。

urls网址

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('page.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

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

settings设置

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_files')

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

views.py (that sends the file) views.py(发送文件)

file_path = os.path.join(settings.STATIC_ROOT+'\\pdf\\free_pdf.pdf')
...
msg.attach_file(file_path)

passenger.wsgi乘客.wsgi

import os
import sys

sys.path.append(os.getcwd())
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

import django.core.handlers.wsgi
from django.core.wsgi import get_wsgi_application
from whitenoise import WhiteNoise
SCRIPT_NAME = os.getcwd()
SCRIPT_NAME = '' #solution for damn link problem

class PassengerPathInfoFix(object):
    def __init__(self, app):
        self.app = app
    def __call__(self, environ, start_response):
        from urllib.parse import unquote
        environ['SCRIPT_NAME'] = SCRIPT_NAME
        request_uri = unquote(environ['REQUEST_URI'])
        script_name = unquote(environ.get('SCRIPT_NAME', ''))
        offset = request_uri.startswith(script_name) and len(environ['SCRIPT_NAME']) or 0
        environ['PATH_INFO'] = request_uri[offset:].split('?', 1)[0]
        return self.app(environ, start_response)
application = get_wsgi_application()
application = PassengerPathInfoFix(application)
application = WhiteNoise(application, root='/home/mysite/mysite/static_files')

(this code is from when I abandoned the media folder and was trying to just serve it with my static files) (此代码来自我放弃媒体文件夹并尝试仅将其与我的静态文件一起使用时)

My proj structure:我的项目结构:

|project
|__app
|__static
|  |__app
|    |__style.css
|__media
|  |__app
|     |__pdfToBeSent
|__static_files (generated by collectstatic)
|__media_files (i created this)

collectstatic also doesn't copy my projects media files into media_files , I have been copying them in there myself (unsure about this). collectstatic 也不media_files我的项目媒体文件复制到media_files ,我自己一直在将它们复制到其中(对此不确定)。

I have also tried moving the media file to every possible location in my project我还尝试将媒体文件移动到我项目中的每个可能位置

I am also serving my static files with whitenoise.我还使用白噪声为我的静态文件提供服务。

Thank you.谢谢你。

Since I was in a similar situation (on the same hosting, A2Hosting), I will try to share my understanding of the problem and the solution I opted for.由于我处于类似的情况(在同一主机上,A2Hosting),我将尝试分享我对问题的理解以及我选择的解决方案。

Pardon me if I may seem presumptuous in this presentation, I'm simply trying to retrace all the points that represent the flow of thoughts that led me to this solution.请原谅我在本次演示中可能显得冒昧,我只是试图追溯所有代表引导我找到这个解决方案的思想流的观点。

A small premise: if with "media files" you intend multimedial files, such as images and so on, I think you shouldn't use the Django media folder as it's designed to serve files uploaded by the users .一个小前提:如果使用“媒体文件”,您打算使用多媒体文件,例如图像等,我认为您不应该使用 Django 媒体文件夹,因为它旨在为用户上传的文件提供服务。
Not knowing if your PDFs are indeed uploaded by some user or not, I'll try to expose my solution anyway.不知道您的 PDF 是否确实是由某个用户上传的,无论如何我都会尝试公开我的解决方案。

When in a production environment, Django isn't going to serve static and media files.在生产环境中,Django 不会提供静态和媒体文件。
For the former I too used WhiteNoise, while for the latter the approach is different (at least on a shared hosting base).对于前者,我也使用 WhiteNoise,而对于后者,方法不同(至少在共享主机基础上)。

When we set Debug = False in settings.py I suspect that the media folder, created along with the Django project, becomes somewhat unreadable/unaccessible (I cannot tell if by the hand of Django or by the hand of the hosting, or a conjuction of the two).当我们在settings.py 中设置Debug = False 时,我怀疑与 Django 项目一起创建的媒体文件夹变得有些不可读/无法访问(我不知道是 Django 的手还是托管的手,还是结合两者中)。

The official method to handle media files is indeed to rely on an external storage service (like Amazon S3), but this solution isn't suitable for budget limited scenarios.官方处理媒体文件的方法确实是依赖外部存储服务(如 Amazon S3),但这种解决方案不适合预算有限的场景。

In my situation, I had the Django app running on a subdomain related to my main domain.在我的情况下,我让 Django 应用程序在与我的主域相关的子域上运行。
Principal domain: www.mydomain.com主域: www.mydomain.com
App domain: subdomain.mydomain.com应用域: subdomain.mydomain.com

Leaving the media folder created with the Django project where it was, I created another one in the following unix path:将使用 Django 项目创建的媒体文件夹留在原处,我在以下 unix 路径中创建了另一个:
/home/A2hosting_username/subdomain.mydomain.com/media /home/A2hosting_username/subdomain.mydomain.com/media

Then, in settings.py I changed the MEDIA_ROOT variable from:然后,在settings.py 中,我将 MEDIA_ROOT 变量从:

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

to:到:

MEDIA_ROOT = '/home/A2hosting_username/subdomain.mydomain.com/media'

After that, in the model.py class used to define the database and interact with it, I specified the path to the uploaded media (videos, in my case) in this way:之后,在用于定义数据库并与之交互的model.py类中,我以这种方式指定了上传媒体(在我的情况下为视频)的路径:

class Video(models.Model):
   name = models.CharField(max_length=50)
   path = models.FileField(upload_to="../media/videos", null=True, verbose_name="")

Since we don't have access to the Apache config file, it may be useful to edit the .htaccess file (relative to subdomain.mydomain.com ) in the following way, to prevent the browser to "time out" when the uploaded file is somewhat heavy:由于我们无权访问 Apache 配置文件,因此按以下方式编辑.htaccess文件(相对于subdomain.mydomain.com )可能很有用,以防止浏览器在上传文件时“超时”有点重:

<ifModule mod_headers.c>
    Header set Connection keep-alive
</ifModule>

I hope this can be of any help.我希望这会有所帮助。

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

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