使用django实现网页的时候,想要在网页上显示图片是一件比较麻烦的事情。标准的html语言显示图片的方法在这里行不通,需要在配置文件中稍作修改。

那么我们可以非常自然想到,网页上的图片的来源方式有两种。1种是静态图片,即在写网页的时候就确定好页面上要放那一张图片。1种是动态图片,如从数据库中的查询得到的图片。这两种显示图片的方式稍有不同,以下分两个部分进行说明。

写在前面:我在做的是django是1.8的版本号,在ubuntu环境下写的。

一、静态图片

假设我们现在已经有了一个可运行的网站,网站的结构如下所示:

.
├── db.sqlite3
├── image
│   ├── admin.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── index.html
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
├── manage.py
├── showImg
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
└── static
    └── 1.jpg

从上述结构可以看出,这个项目的名字叫做“showImg”,而APP的名字叫做“image”。至于其他各个文件的作用我就不再一一赘述,如果对这些文件还不是很明白的话,建议可以先从基本的入手。

在我们的主页面中,index.html文件希望现实static文件夹下面的这个图片,目前index.html的内容如下:

<!-- index.html -->
<
html> <head><head> <body> <h1>An Image Test</h1> <img src="/static/1.jpg"> </body> </html>

按照传统的理解,这个时候图片是可以现实的,但在django中,图片显示的是一个“×”,图片无法显示出来。

这是因为按照django处理链接的习惯,每次django遇到一个链接,都会到urls.py中寻找相应的解决方案。而urls.py中也给出各个链接对应的views.py文件中的处理函数,所以这个时候我们需要修改urls.py文件。当然,这个urls.py文件是image文件夹下的,而不是showImg文件夹下的。

# ./image/urls.py
from
django.conf.urls import patterns, url from image import views urlpatterns = patterns('', url(r'^$', views.show, name='index'), url(r'^static/(?P<path>.*)', 'django.views.static.serve', {'document_root':'/home/anna/Documents/django_py/showImg/static'}), )

标红的内容就是要新添加的一行说明,告诉django,当遇到一个“static”开头的链接时,改如何处理。

这个时候,再访问http://127.0.0.1:8000/image/ 发现,图片还是无法显示,我们还需要小小的修改一下index.html中的内容

<!-- index.html -->
<html>
<head><head>
<body>
    <h1>An Image Test</h1>
    <img src="static/1.jpg">
</body>
</html>

这个地方和前面的代码有什么不同呢?就是图片路径不在是绝对路径而是相对路径了(呃,其实我也不知道为什么,我也是尝试了好久才发现应该是这个样子的。恩。)

这个时候再访问http://127.0.0.1:8000/image/就没问题啦!

然后我们又会有一个问题,我习惯把图片放在别的目录下面,放在根目录的static下面不符合我的习惯。这个时候再要修改,也就是非常方便的事情了。

.
├── db.sqlite3
├── image
│   ├── admin.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── index.html
│   ├── pic
│   │   └── 1.jpg
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
├── manage.py
├── showImg
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
└── static
    └── 1.jpg

比如说将图片放在image/pic/目录下,那么这个是我们首先修改urls.py文件的内容。

# ./image/urls.py
from django.conf.urls import patterns, url
from image import views
 
urlpatterns = patterns('',
         url(r'^$', views.show, name='index'),
         url(r'^image/pic/(?P<path>.*)', 'django.views.static.serve', {'document_root':'/home/anna/Documents/django_py/showImg/image/pic'}),
         ) 

注意到绿色高亮的部分,就是把原先的“static”全部都换成了新的路径。相应的,index.html文件也是一样的处理方式。

<!-- index.html -->
<html>
<head><head>
<body>
    <h1>An Image Test</h1>
    <img src="image/pic/1.jpg">
</body>
</html>

这样再访问http://127.0.0.1:8000/image/就也可以了

当然,所谓一样通样样通,万变不离其宗,为了保证接口的一致性,我们也可以保留static关键字,而只修改图片的位置。这个时候的代码如下:

# ./image/urls.py
from django.conf.urls import patterns, url
from image import views
 
urlpatterns = patterns('',
         url(r'^$', views.show, name='index'),
         url(r'^static/(?P<path>.*)', 'django.views.static.serve', {'document_root':'/home/anna/Documents/django_py/showImg/image/pic'}),
         ) 
<!-- index.html -->
<html>
<head><head>
<body>
    <h1>An Image Test</h1>
    <img src="static/1.jpg">
</body>
</html>

发现其中的不同了吗?这样也是可以的哦。

=========================

上面的方法基本可以满足我们的需要啦,但是因为种种原因,我们选择另一种方法来解决这个问题。

还是从最基本的说起,项目结构如下,图片在static文件夹下。

.
├── db.sqlite3
├── image
│   ├── admin.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── index.html
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
├── manage.py
├── showImg
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
└── static
    └── 1.jpg

首先需要在showImg/settings.py文件中加一句话

# showImg/settings.py
STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static').replace('\\', '/'), )

红色的就是添加的话,不用做任何改动(前提是图片在static文件夹下)。然后再修改index.html的内容:

<!-- index.html -->
<html>
<head><head>
<body>
    <h1>An Image Test</h1>
   {% load staticfiles %} <img src="{% static"1.jpg"%}"> </body> </html>

着重要修改的内容如红色高亮。这里需要注意的是,img的src的内容中,1.jpg的前后是不能要空格的,否则图片的路径将会是错误的。

<img src="{% static"1.jpg "%}">

比如上述代码,这样的图片路径是有错误的。

如果大家发现图片无法显示的话,可以用“审查元素”看一下图片的路径是否正确,正确的图片路径应该是:

<img src="/static/1.jpg">

相应的,如果大家不习惯把图片的内容放到static文件夹下面的话,这里只用改一处就可以了:

# showImg/settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = (
     os.path.join(BASE_DIR, 'image/pic').replace('\\', '/'),
)

然后在index.html文件中,还是使用static来访问图片。

 

二、动态图片

动态图片的处理过程与静态图片没有根本上的区别。我们还是承接上面的例子来思考,如果用户上传的动态图片就是存储在/static文件夹下面的,我们怎么办呢?

.
├── db.sqlite3
├── image
│   ├── admin.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── index.html
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
├── manage.py
├── showImg
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
└── static
    └── 1.jpg

现在我们假设前面的静态图片的目的已经成功了,只不过现在新添加了一个功能,是上传图片,并将图片存储在/static文件夹下。

这时候我们自然想到,要将上传的图片显示到网页上,首先要从视图层(views.py)中将要显示的图片信息传给网页,假设图片信息是图片名称,即本例中的“1.jpg”,那么views.py的部分代码为:

# views.py

return render_to_response('index.html', {'images':'1.jpg'})

当把要显示的图片传递给网页后,index.html的代码就有所改变了:

<!-- index.html -->
<html>
<head><head>
<body>
    <h1>An Image Test</h1>
   {% load staticfiles %}   
    <img src="{% static images %}">
</body>
</html>

改变只如红色高亮部分,将原来的具体的图片名称改成了传递过来的内容指代。当然,如果在views.py中传递过来的图片不只1张的话,即:

# views.py

return render_to_response('index.html', {'images':['1.jpg', '2.jpg']})

如上述代码,传递的是一个list,index.html采用上面的代码是无法正确显示出图片的。通过审查元素看到的图片的url是乱码,这个时候我们就要循环显示图片了:

<!-- index.html -->
<html>
<head><head>
<body>
    <h1>An Image Test</h1>
   {% load staticfiles %}  
   {% for img in images %}
<img src="{% static img %}">
   {% endfor %}
</body> </html>

这个时候必须如上述代码中循环显示图片才能正确显示。

===========================

好了,到这里我们已经分别讲述了如何显示静态和动态的图片了。但是如果当一个网站里面同时包含静态和动态的图片的话,就还是需要使用不同的指代方式——“static”和“media”。static的内容我们已经讲过了,如果是动态图片的话,media如何使用:

# settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media').replace('\\','/')
MEDIA_URL = '/media'

在settings.py中加入如上内容。然后修改online/models.py中的内容,将上传的图片显示到media文件夹下

# online/models.py

class Image(models.Model):
    headImg = models.FileField(upload_to = '.')

其中标红处的文件路径是比较关键的。这里只写一个当前路径,而不再写文件夹的名称,是因为在settings.py文件中已经指定了上传文件的位置,就是在/media 文件夹下,所以这里不用再指定了。如果在这里写成

# online/models.py

class Image(models.Model):
    headImg = models.FileField(upload_to = './media')

就会发现,上传的图片其实是保存在/media/media文件夹下面的。

这时,再将图片信息传递给页面,让页面显示,就可以了:

<!-- index.html -->
<html>
<head><head>
<body>
    <h1>An Image Test</h1>
   {% load staticfiles %}  
   {% for img in images %} 
    <img src="{% static img %}">
   {% endfor %}
</body>
</html>

注意,这里依然用static作为关键字,而不因为是动态文件就用media之类的。

 

 

 

 

 

 

 

 

 

Bon Appetite!