在Django中访问“媒体”文件


67

我想爱Django,但是开发环境中的静态文件和媒体文件业务让我发疯。请把我从愚蠢中解救出来。

我在开发机器上。media我的项目目录的根目录中有文件夹。

settings.py我有:MEDIA_ROOT = ''MEDIA_URL = '/media/'

urls.py我有:

if settings.DEBUG:
    urlpatterns += patterns('',
        url(r'^media/(?P<path>.*)$',
            'django.views.static.serve',
            {'document_root': settings.MEDIA_ROOT, }),
    )

但是我获取媒体文件的唯一方法是引用/media/media/例如 <img src="/media/media/image.png" />

我期望(并且想要)
<img src="/media/image.png" />

谁能告诉我这里发生了什么,并给我一个简单的方法来设置媒体文件处理吗?

非常感谢你。


@Timmy O'Mahony-谢谢!史诗般的帖子,而且很清晰。但这留下了两个问题:

(1)我必须用/media//static/,不media/static/MEDIA_URL和与STATIC_URL-我这么想吗?

(2)如果是collectstatic软管/static/,您将站点级CSS放置在哪里,例如站点的CSS文件?/static/显然不在。

(3)我将它们放在项目根目录下的目录“ _”中并STATICFILES_DIRS指向它-这似乎是开发服务器获取其静态文件的位置,尽管有该urlpatterns指令。如果那是错误的,那么在开发期间您将站点级CSS放在哪里,以及collectstatic在修改它们时的工作流程是什么-您是否必须在一个位置进行编辑,并在每次编辑后将其收集在其他位置?

Answers:


29

为什么将MEDIA_ROOT设置设为空白?它必须是您的媒体目录的路径。如您所说,由于媒体位于子目录中media,因此应将其放在中MEDIA_ROOT


1
具体来说,应该是MEDIA_ROOT = "media/"
melinath 2011年

7
我更喜欢使用绝对路径来避免问题。我在settings.py中为此使用了一个小包装: import os.path ABSOLUTE_PATH = lambda x: os.path.join(os.path.abspath(os.path.dirname(__file__)), x) MEDIA_ROOT = ABSOLUTE_PATH('media/')
2011年

178

文件夹设置:

您的项目根目录应类似于:

/app1
/app2
/media
/static
/templates
urls.py
settings.py
manage.py

媒体文件夹应该像图片,下载等材料装东西,可能正常使用本网站的过程中被上传(开发完成后,即)

静态文件夹应该容纳所有的CSS / JS等材料是网站发展的一个组成部分


Settings.py:

MEDIA_ROOT是上述静态文件夹的绝对服务器路径。这意味着应该是这样的:

MEDIA_ROOT = "/User/Bob/Sites/MySite/Project_root/media/"

MEDIA_URL是当您查看站点时应该从中访问媒体文件的相对浏览器URL。它应该(通常)

MEDIA_URL = "media/"

这意味着可以在http://example.com/media/上查看所有资料

同样,STATIC_ROOT应该类似于

STATIC_ROOT = "/User/Bob/Sites/MySite/Project_root/static/"

STATIC_URL

STATIC_URL = "static/" 

提供文件:

既然您已经告诉django这些文件夹应该在哪里,以及访问它们的正确URL,那么您就需要正确地向这些文件夹提供所有请求。

通常,当您在生产中时,您希望Web服务器负责服务静态文件和媒体文件。

如果您正在开发,则只需获取django开发服务器即可为您提供服务。

要做到这一点,你告诉它路由进来的所有请求http://example.com/media您MEDIA_ROOT和进来的所有请求http://example.com/static您STATIC_ROOT。

为此,您可以像下面这样向URLS.py添加一些URL:

from django.conf import settings
if settings.DEBUG:
    urlpatterns += patterns('',
        url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
            'document_root': settings.MEDIA_ROOT,
        }),
        url(r'^static/(?P<path>.*)$', 'django.views.static.serve', {
            'document_root': settings.STATIC_ROOT,
        }),
)

额外

如果您有多个应用程序,每个应用程序都有自己的CSS和JS文件,则可能不想将它们放在一个/ static /文件夹中。将它们放在它们所属的应用程序的子文件夹中可能会很有用:

/app1/static/ # Specific static folder
/app2/static/
/media/
/static/ # Root static folder

现在,您的Web服务器/开发服务器仅在您要查找的静态文件(即静态根目录)中查找,因此您需要收集子文件夹中的所有文件并将其复制到静态根目录中。您可以手动执行此操作,但是django提供了一个命令为您执行此操作(这是静态应用程序的重点)

./manage collectstatic

3
谢谢,我完全忘记了开发服务的“静态服务”,想知道为什么我的文件没有被提供。如果可以的话,我会进一步赞扬您的帖子;)
马丁


很好的答案和发布。但是,您可能想要添加到博客文章中的内容是显式添加媒体context_processor,如该答案所述。否则,如我所知,很难<img src="{{ MEDIA_URL }}{{ evt_pic }}">在模板中进行定义。从1.8开始,尚未明确添加。
约翰·C

1
说了这么多的media context_processor需要,我只是读了对方的回答相同的问题,有趣的是,ImageFields还提供了一个网址,所以实际上是在context_processor和MEDIA_URL没有必要:src="{{artist.artist_image.url}}
约翰·C·

到目前为止,该博客文章可能是有关Django静态文件的最全面,最易理解的文章。您是否还想打开博客文章上的评论以进行讨论?
阿南帕姆

16

我遵循了timmy的步骤,但是出现了“ No module name”(无模块名称)错误django.views。当我import django.views在virtualenv中使用时,一切正常,即,导入库不是问题。

但是,我可以通过在主url文件中执行以下过程来解决此问题

from django.conf.urls.static import  static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

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


10

我遇到了同样的问题,所以我添加了以下几行

from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    url(r'', include('blog.urls')),
    url(r'^admin/', admin.site.urls),
    url(r'^cadmin/', include('cadmin.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

urls.pyDjango项目配置目录中。更多信息:https : //overiq.com/django/1.10/handling-media-files-in-django/


4

在您的settings.py中,确保添加

django.core.context_processors.media

在TEMPLATE_CONTEXT_PROCESSORS中使用。否则,当您在模板中使用MEDIA_ROOT时,它将无法使用。


1
不需要,自Django 1.9.4起
Darshan Chaudhary

3

我正在使用Django 1.10。我的媒体文件夹为“上传”,这是我的settings.py中的配置:

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

在模板中,我将名称o MEDIA_URL放在de object.name之前,而不是object.url,如下所示:

    <img src="uploads/{{ imagen_identificativa.name }} " alt="{{imagen_identificativa}}">

它对我有用。我希望这有帮助。


0

这是另一种选择:

在“ settings.py”中设置您的媒体配置,如下所示:

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

可以说我有一个模态调用人,其图像文件如下所示:

class Person(models.Model):
    name = models.CharField(max_length = 30)
    photo = models.ImageField(upload_to = 'photos')

现在在这里,我们要使用的upload_to路径位于MEDIA_ROOT文件夹中。以我为例,将在其中创建一个媒体文件夹,在其中创建照片文件夹,并将此处的我们的媒体转储。

因此,现在在我的模板中,我将执行以下操作:

<img src="{{ person.photo.url}} />

简而言之,您得到了一个字段,像这样使用它:

src ={{ object.field.url}}

希望有帮助!编码愉快!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.