静态文件指像css,js,images之类的文件,在Django里面静态文件的处理与一般的视图是不一样,新手往往容易犯迷糊,本文做一下总结:
一、概述:
静态文件交由Web服务器处理,Django本身不处理静态文件。简单的处理逻辑如下(以nginx为例):
URI请求-----> 按照Web服务器里面的配置规则先处理,以nginx为例,主要求配置在nginx.conf里的location
|---------->如果是静态文件,则由nginx直接处理
|---------->如果不是则交由Django处理,Django根据urls.py里面的规则进行匹配
以上是部署到Web服务器后的处理方式,为了便于开发,Django提供了在开发环境的对静态文件的处理机制,方法是这样:
1、在INSTALLED_APPS里面加入'django.contrib.staticfiles',
2、在urls.py里面加入
- 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}), )
3、这样就可以在开发阶段直接使用静态文件了。
二、MEDIA_ROOT和MEDIA_URL
而静态文件的处理又包括STATIC和MEDIA两类,这往往容易混淆,在Django里面是这样定义的:
MEDIA:指用户上传的文件,比如在Model里面的FileFIeld,ImageField上传的文件。如果你定义
MEDIA_ROOT=c:\temp\media,那么File=models.FileField(upload_to="abc/"),上传的文件就会被保存到c:\temp\media\abc
举个例子:
- class blog(models.Model):
- Title=models.charField(max_length=64)
- Photo=models.ImageField(upload_to="photo")
上传的图片就上传到c:\temp\media\photo,而在模板中要显示该文件,则在这样写{{MEDIA_URL}}blog.Photo
在settings里面设置的MEDIA_ROOT必须是本地路径的绝对路径,一般是这样写
- PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
- MEDIA_ROOT=os.path.join(PROJECT_PATH,'media/').replace('\\','/')
MEDIA_URL是指从浏览器访问时的地址前缀,举个例子:
- MEDIA_ROOT=c:\temp\media\photo
- MEDIA_URL="/data/" #可以随便设置
在开发阶段,media的处理由django处理:
访问http://localhost/data/abc/a.png就是访问c:\temp\media\photo\abc\a.png
在模板里面这样写<img src="{{MEDIA_URL}}abc/a.png">
在部署阶段最大的不同在于你必须让web服务器来处理media文件,因此你必须在web服务器中配置,以便能让web服务器能访问media文件
以nginx为例,可以在nginx.conf里面这样:
location ~/media/{
root /temp/
break;
}
具体可以参考如何在nginx部署django的资料。
三、STATIC_ROOT和STATIC_URL、
STATIC主要指的是如css,js,images这样文件,在settings里面可以配置STATIC_ROOT和STATIC_URL,配置方式与MEDIA_ROOT是一样的,但是要注意
STATIC_ROOT与MEDIA_ROOT位置不能一样。
STATIC文件一般保存在以下位置:
1、STATIC_ROOT:在settings里面设置,一般用来放一些公共的js,css,images等。
2、app的static文件夹,在每个app所在文夹均可以建立一个static文件夹,然后当运行collectstatic时,Django会遍历INSTALL_APPS里面所有app的static文件夹,将里面所有的文件复制到STATIC_ROOT。因此,如果你要建立可复用的app,那么你要将该app所需要的静态文件放在static文件夹中。
也就是说一个项目引用了很多app,那么这个项目所需要的css,images等静态文件是分散在各个app的static文件的,比较典型的是admin应用。
当你要发布时,需要将这些分散的static文件收集到一个地方就是STATIC_ROOT。
3、STATIC文件还可以配置STATICFILES_DIRS,指定额外的静态文件存储位置。
STATIC_URL的含义与MEDIA_URL类似。
四、小结
如果你发生在部署阶段找不到css,js,则可能是以下几个问题:
1、web服务器配置有问题,不同的部署方式对静态文件的处理有所不同。
2、没有运行collectstatic将所需要的静态文件收集到STATIC_ROOT
===============
- MEDIA_ROOT:主要是为了存放上传的文件,比如在ImageField中,这个值加上upload_to的值就是真实存放上传图片的文件位置;Django里边文件内容实际上是不会存放到数据库里边的,大多数数据库存放数据效率低,需要保存在文件系统里。PS:FileUploads(用来存储文件)
- MEDIA_URL:URL的映射,前后要加上‘/’ 表示从根目录开始,比如“/site_media/”,加上这个属性之后,静态文件的链接前面会加上这个值。
- STATIC_ROOT:在这个文件里边的目录会当成静态文件处理。但是不能把自己辛苦写的Javascript或者图片等静态文件放进去。
- STATIC_URL:URL映射,指定静态目录的URL,默认的是"/static/"。
- STATICFILES_DIRS:指定一个工程里边哪个目录存放了与这个工程相关的静态文件,是一个列表。如果列表中有一个是 “/home/shishang/test/static”,其中有一个文件内容是productlist.html, 我们只要访问http://localhost:8000/static/productlist.html就可以直接访问界面了。
- 转:Django提供了一个方法自动地将所有的静态文件放在一起。只要在写App的时候创建一个static子目录专门保存静态文件就行了。在开发阶段,不必费心去做映射,不需要配置
urls.py
。在布署到生产环境的时候,只需要配置Apache把/static/
映射到STATIC_ROOT
。然后运行manage.py collectstatic
,自动地STATICFILES_DIRS
列出的目录以及各个App下的static子目录的所有文件复制到STATIC_ROOT。因为复制过程可能会覆盖掉原来的文件,所以,一定不能把我们辛苦做出来静态文件放这边!在开发阶段,Django把/static
映射到django.contrib.staticfiles
这个App。staticfiles
自动地从STATICFILES_DIRS
、STATIC_ROOT
以及各个App的static
子目录里面搜索静态文件。一旦布署到开发环境上,settings.py不需要重新编写,只要在Apache的配置文件里面写好映射,/static
将会被Apache处理。django.contrib.staticfiles
虽然仍然存在,但因为不会接收到以/static/
开始的路径,所以将不会产生作用。不必担心Django会使用处理速度变慢。另外,当settings.DEBUG is False
的时候,staticfiles
将自动关闭。 - 具体代码示例:
- #setting.py 中加入:
- import os
- HERE = os.path.dirname(os.path.dirname(__file__))
- MEDIA_ROOT = os.path.join( HERE, "../media").replace('\\', '/')
- MEDIA_URL = "/site_media/"
- STATIC_ROOT = os.path.join(HERE, "../static").replace('\\', '/')
- STATIC_URL = "/static/"
- STATICFILES_DIRS = ( os.path.join(HERE, "../app名字/static/").replace('\\', '/'), ) #和STATIC_ROOT最好路径不要重叠
- #建议将静态文件保存在app的static目录中
- #urls.py中加入:
- from django.conf.urls.static import static
- from django.conf import settings
- urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
- urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
- #这样使用
- <link type="text/css" rel="stylesheet" href="/static/css/bootstrap.min.css"/>
- <link type="text/css" rel="stylesheet" href="/static/css/bootstrap-responsive.css"/>