Django静态URL无法正确呈现图像

时间:2012-10-31 00:58:57

标签: python html django url static

我正在编写一个在页面上显示一组图像的视图。

这是模型

#models.py
class Movie(models.Model):
    title  = models.CharField(max_length = 500)
    poster = models.ImageField(upload_to = 'qanda/static/movie_posters')

#index.html
    <img src = "{{ STATIC_URL }}movie_posters/{{ movie.poster }}"></a>

当我运行服务器时,图像不会出现。图像尝试加载的URL是

http://127.0.0.1:8000/static/movie_posters/qanda/static/movie_posters/image.jpg

当它应该尝试加载的URL是

http://127.0.0.1:8000/static/movie_posters/image.jpg

我的假设是,因为movie.poster位于'qanda / static / movie_posters',当我在HTML上呈现它时,它正在加载静态URL(127.0.0:8000 /静态),然后是位置'qanda最后是/ static / movie_posters'。如何正确渲染图像?

3 个答案:

答案 0 :(得分:6)

图像网址的计算方法有两部分。

首先在settings.py中定义MEDIA_ROOTMEDIA_ROOT指定计算机上存储媒体的绝对文件夹。例如,对于这些设置:

MEDIA_ROOT = '/abs/path/to/media/'

如果你有一个字段

models.ImageField(upload_to='movie_posters')

然后图像将存储在:

/abs/path/to/media/movie_posters/
/abs/path/to/media/movie_posters/poster.jpg <- example

这涉及媒体存储在硬盘上的位置。

第二部分是如何计算这些媒体文件的网址。为此,您在MEDIA_URL中定义settings.py。这实际上是将网址映射到您的MEDIA_ROOT位置。那么,如果您的MEDIA_URL是:

MEDIA_URL = 'http://localhost/media/'

然后,如果您要访问存储在movie_posters/poster.jpg的图片,其绝对路径为/abs/path/to/media/movie_posters/poster.jpg,则其网址应为http://localhost/media/movie_posters/poster.jpg。您可以通过执行以下操作来计算URL:

{{ MEDIA_URL }}{{ movie.poster }}

请注意,我使用MEDIA_URL代替STATIC_URL。那些不是一回事。然而,计算这样的网址并不是很整洁。这就是为什么Django的ImageFieldFileField具有url属性的原因:

{{ movie.poster.url }}
然后,Django将根据您的MEDIA_URL设置计算正确的网址。

注意:

要使所有这些工作,您必须运行单独的媒体服务器。 Django不提供任何媒体文件。在开发中,它只能提供静态文件(与媒体文件不同)。因此在开发中,提供媒体文件的一个好方法是使用Python的简单Web服务器。为此,打开一个新终端(在Linux和Mac上)或命令提示符(在Windows上)窗口/选项卡,然后导航到您的媒体文件夹。然后在那里执行以下命令:

python -m SimpleHTTPServer 8090

并确保您的设置为:

MEDIA_URL = 'http://localhost:8090/'

然后Python将为您的媒体文件提供服务。这很适合开发。

答案 1 :(得分:1)

如果您只想使用开发服务器来提供媒体服务,可以暂时将其添加到您的urls.py

urlpatterns = patterns( ...all your awesome urls...) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

答案 2 :(得分:0)

您可以定义一个自定义模板标记,它返回URL的基本名称,如下所示:

from django import template
import os

register = template.Library()

@register.filter
def getBasename(myURL):
   return os.path.basename(myURL)

这应该放在您应用的 templatetags 目录中的自定义模板标记(例如customTemplateTags.py)文件中。

然后您可以使用过滤器来获取图像文件名,而不是整个URL。

{% load customTemplateTags %}
<img src = "{{ STATIC_URL }}movie_posters/{{ movie.poster.url|getBasename }}"></a>