Add New Notes

This commit is contained in:
geekard
2012-08-08 14:26:04 +08:00
commit 5ef7c20052
2374 changed files with 276187 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-27T15:15:15+08:00
====== Developing Reusable Django Apps ======
Created Thursday 27 October 2011

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -0,0 +1,195 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-22T19:56:25+08:00
====== Django+Mysql安装配置详解(Linux)[更新为1.3版] ======
Created Saturday 22 October 2011
http://dmyz.org/archives/110
===== Perface =====
Django是一个开源的Web应用框架由Python写成并于2005年7月在BSD许可证下发布。Django的主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django采用MVC设计模式,注重组件的重用性和“可插拔性”敏捷开发和DRY法则Dont Repeat Yourself
在Django中Python被普遍使用甚至包括配置文件和数据模型。本文介绍Django在Linux+Mysql环境下安装、配置的过程包括安装、运行、添加应用的所有流程最终建立一个可以从Mysql读取文章并显示的Django应用。
===== Install =====
首先下载Django
wget www.djangoproject.com/download/1.3/tarball/
得到Django-1.3.tar.gz将其解压后安装
tar xzvf Django-1.3.tar.gz
cd Django-1.3
sudo python setup.py install
如果提示缺少setuptools还要下载安装setuptools(建议提前安上因为在安装MySQL for Python的时候也会用到)。
完成安装后Django会拷贝一个**django-admin.py**到/usr/local/bin下这个py文件引入了**Django的管理模块**。
===== Setup =====
要创建一个Django项目非常简单使用startproject命令输入项目名称
**django-admin.py startproject mysite**
Django会在当前目录下自动生成一个名为mysite的文件夹即**项目文件夹**,里面有以下文件(.pyc在第一次执行后才有刚建立时可能只有几个.py后缀的文件)
urls.py
settings.pyc
settings.py
manage.py
__init__.pyc
__init__.py
__init__.py/__init__.pyc可以是空文件只是**表明这个文件夹是一个可以导入的包**,这个文件在安装配置时不会用到。
settings.py/settings.pyc配置文件配置Django的一些信息最主要是数据库信息、加载模块的信息。
manage.py**命令行工具**实现与Django之间的交互。
创建项目后,进入项目文件夹,启动**Django自带的web开发服务器**
python manage.py runserver
Django会自动检查配置文件中的错误如果全部正常则顺利启动
Validating models…
0 errors found
Django version 1.2.3, using settings mysite.settings
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
访问http://127.0.0.1:8000如果顺利显示说明Django已经可以正常使用了。但现在只有本机可以访问要让外网能够访问或是要更换默认的8000端口可以执行命令
python manage.py runserver 0.0.0.0:8080
这样就将端口修改为8080且外网也可以通过IP访问本机上的Django。
现在要让Django支持Mysql数据库。编辑配置文件(settings.py)。在第12行找到
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', #设置为mysql数据库
'NAME': 'dmyz', #mysql数据库名
'USER': 'root', #mysql用户名留空则默认为当前linux用户名
'PASSWORD': '', #mysql密码
'HOST': '', #留空默认为localhost
'PORT': '', #留空默认为3306端口
}
}
再次使用runserver命令(通常来说Django会**自动重新加载settings.py文件**的)就可以使用Mysql数据库了。
因为Django要通过Python操作Mysql所以要先安装**Mysql for Python**。在Ubuntu下安装还会提示EnvironmentError: mysql_config not found。因为通过apt-get安装的mysql**没有安装开发工具包**所以找不到mysql_config文件使用以下命令安装
sudo apt-get install libmysqld-dev
===== URL =====
URL配置文件很象**一个目录**Django会通过URL配置文件来查找相应的对象URL地址的使用正则表达式设置。在mysite目录下可以找到urls.py文件它是URL配置的默认起点也可以通过编辑settings.py中的 __ROOT_URLCONF__值来修改。直接编辑urls.py
urlpatterns = patterns('',
(r'^$', 'mysite.hello.index'),
)
r^$’:正则,表示根目录;
mysite.hello.index指向mysite这个项目下的hello模块中的index函数。
剩下的就很简单了在mysite文件夹下建立一个hello.py文件在其中写入一个index函数
#hello.py
from django.http import HttpResponse
def index(request):
return HttpResponse('hello, world')
刷新网站首页就可以看到已经输出了”hello, world”。
另一种方法: 设置一个hello模块只是方便理解Django的结构但如果一个首页就要使用那么多代码是很不pythonic的所以在生产环境中我们的首页通常会这么来写
#url.py
urlpatterns = patterns('',
url(r'^$', 'django.views.generic.simple.direct_to_template', {'template':'index.html'}),
)
Django会自动**在模板目录中**找到并加载index.html只需要修改url.py一个文件就搞定了。
===== Application =====
上一节”hello world”的例子只是说明了URL的用法可以说完全没有用到Django。__Django作为一个Web框架目的是实现MVC的分离它可以自行处理一些通用的操作让开发人员可以专注于核心应用的开发。__所以本文的最后一步将编写一个名为article的应用从mysql数据库里读取出文章作者、标题、内容。
首先建立应用:
python manage.py startapp article
在项目文件夹中会增加一个article文件夹里面有如下文件
models.py
views.py
__init__.py
models.py模型文件用一个 Python 类来描述**数据表**,运用它可以通过简单的 Python 的代码来创建、检索、更新、删除数据库中的记录而无需写一条又一条的SQL语句。
views.py视图文件用来联系模型与模版。
然后编写模型文件(article/models.py),用来实现对数据库的操作:
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=50)
author = models.CharField(max_length=50)
content = models.CharField(max_length=200)
现在要修改配置文件(settings.py)文件告诉Django这__个应用是项目的一部分__打开配置文件在尾部找到INSTALLED_APPS元组将article添加进去
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django_openid_auth',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
#……
'mysite.article', #加入app
)
可以现运行manage.py sql article命令进行测试如果可以看到生成的sql语句说明模型已经正常设置可以初始化并安装
python manage.py syncdb
Django会自动创建名为**article_article**的表。而且因为在INSTALLED_APPS中使用了__django.contrib.auth__所以syncdb命令会要求提供一个管理员帐号和密码用来登录Django的管理工具。
You just installed Djangos auth system, which means you dont have any superusers defined.
Would you like to create one now? (yes/no): yes
简单的模型就设置完成了,现在来设置视图,编辑视图(article/views.py)文件:
# article/views.py
from django.shortcuts import render_to_response
from models import Article
def latest_article(request):
article_list = Article.objects.order_by('-id')
return render_to_response('article/article.html',{'article_list':article_list})
2行导入Django的render_to_response()函数,它用来调用模板、填充内容和返回包含内容的页面。
3行导入之前编写模型文件中的Article类。
4~6行定义一个latest_article函数利用Article类从数据库获得数据并按照id倒序输出。然后调用模版文件将变量传递过去。
在上面的代码中使用的模版文件它的地址是设置文件中的__模版路径__+在views.py中定义的路径因此如果报错TemplateDoesNotExist at 路径的话,很可能就是忘了设置模板路径。
编辑设置文件(settings.py),修改**TEMPLATE_DIRS**,设置一个模版路径,这里将模版目录直接指定在项目文件夹(mysite)中:
TEMPLATE_DIRS = (
"/var/www/mysite"
)
这样程序运行时,加载的静态模版就是 /var/www/mysite/article/article.html了。如果使用过其它框架或者模板引擎下面article.html的内容就很容易看懂了Django在模版文件中利用相应的TAG控制传递过来的变量显示的位置
{% for article in article_list %}
Author:{{ article.author }}
Title:{{ article.title }}
Content:{{ article.title }}
{% endfor %}
最后修改URL配置文件让article/指向视图(views.py)中定义的latest_articl函数
(r^article/, mysite.article.views.latest_article),
这样所有的配置就完成了,当访问 http://127.0.0.1:8000/articleDjango就会自动读取数据库中的内容并显示在网页上了。
===== Epilogue =====
本文的一些设置并不适用于实际生产环境比如URL配置为了方便重用通常都会__使用include的方式__而在这里则是直接指定。所以本文旨在介绍一些入门知识和快速配置的方法如果希望更规范的学习Django首推Django的官方文档其次是Djangobook我更新这篇文章的时候Djangobook2.0中文版已经翻译了大半了也是学习Django很好的教材。

View File

@@ -0,0 +1,107 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-27T15:30:19+08:00
====== Django tips- laying out an application ======
Created Thursday 27 October 2011
http://www.b-list.org/weblog/2006/sep/10/django-tips-laying-out-application/
Continuing the theme of dealing with common questions from the Django mailing lists and IRC channel, today well look at how to organize the various bits of a Django-based project or application.
===== Projects versus applications =====
This is really more of a separate (though related) question, but understanding the distinction Django draws between a “project” and an “application” is a big part of good code layout. Roughly speaking, this is what the two terms mean:
* An application tries to provide a single, relatively self-contained set of related functions. An application is allowed to define a set of models (though it doesnt have to) and to define and register custom template tags and filters (though, again, it doesnt have to).
* A project is a collection of applications, installed into the **same** database, and all using the same settings file. In a sense, the defining aspect of a project is that it supplies a settings file which specifies the database to use, the applications to install, and other bits of** configuration**. A project may correspond to a single web site, but doesnt have to — multiple projects can run on the same site. The project is also responsible for the** root URL** configuration, though in most cases its useful to just have that consist of calls to include which pull in URL configurations from inidividual applications.
Views, custom manipulators, custom context processors and most other things Django lets you create can all be defined **either **at the level of the project or of the application, and where you do that should depend on whats **most effective** for you; in general, though, theyre best placed **inside an application** (this increases their portability across projects).
===== Default project-level file layout =====
When you run** django-admin.py startproject**, Django will automatically create a new directory containing four files:
* __init__.py, which will be empty. This file is required to tell Python that the directory is a Python module and can be imported (and imported from).
* manage.py, which provides a number of convenience functions for working with the project.
* settings.py, which will be the projects settings file.
* urls.py, which will be the projects **root **URL configuration.
Generally you dont need to modify this layout, and for compatibility and consistency its probably **best if you dont**. If you do want to change things, though, heres what its safe to do:
* You can put your settings in a file thats not called settings.py — Django finds out where your settings are by looking at the environment variable **DJANGO_SETTINGS_MODULE**, not by looking for a file with a specific name.
* You can put your root URL configuration somewhere thats not called urls.py — Django looks at the **ROOT_URLCONF **settingin settings.py file to find out where your URL configuration lives.
manage.py and __init__.py should be left alone.
===== Default application-level file layout =====
When you run **manage.py startappon the root of project directory**, Django creates a sub-directory of your project directory, and creates the following files:
* __init__.py, which serves the same purpose as at the project level.
* models.py, which should hold the applications model classes.
* views.py, which is for any custom views the application wants to provide.
The __init__.py and models.py files (or, if you want to split up your models across multiple files, a directory called __models __which can act as a Python module) are **required**; without __init__.py, Python wont be able to import from the application, and Django is **hard-wired** to expect models in a file or module called models. The views.py file, however, is **optional** and you can delete it if you wont be providing any views, or rename it if you want to call it something else (though for sake of **consistency **its probably best not to rename it).
===== Extra special stuff =====
There are four “**special**” locations inside your application which can be used in order to take advantage of specific features, so if you want to use these features you dont have a whole lot of choice in how you set them up:
* To define custom template tags or filters, you must create a sub-directory in the applications directory called **templatetags**, and it **must **contain a file named __init__.py so that it can be imported as a Python module.
* To define** unit tests** which will **automatically** be noticed by Djangos testing framework, put them in a module called **tests** (which can be either a file named tests.py or a directory called tests). The testing framework will also find any **doctests **in that module, but the preferred place for those is, of course, the docstrings of the classes or functions theyre designed to test.
* To provide custom SQL which will be executed immediately after your application is** installed**, create a sub-directory called__ sql __inside the applications directory; the file names should be the same as the names of the models whose tables theyll operate on; for example, if you have an app named weblog containing a model named Entry, then the file __sql/entry.sql __inside the apps directory can be used to modify or insert data into the entries table as soon as its been created.
* To provide custom Python functions which will run when the application is installed, put them in a file named __management.py__, and use Djangos internal dispatcher to connect your functions to the **post_syncdb** signal.
That last one deserves a bit more explanation, so lets look at it in detail.
Internally, Django uses a package called **PyDispatcher** to enable its various bits to communicate cleanly with each other. Basically, the dispatcher works like this:
* Various parts of Django, as well as other applications, define plain objects called “signals”.
* Code which wants other things to be notified of something happening tells the dispatcher to send a particular signal.
* Code which wants to be notified when something happens uses the dispatchers connect method to listen for a particular signal.
For example, if you wanted to set up a function which would execute any time a new application is installed, you could create a file in your application called management.py, and put this code in it:
from django.dispatch import dispatcher
from django.db.models import signals
def my_syncdb_func():
# put your code here...
dispatcher.connect(my_syncdb_func, signal=signals.post_syncdb)
Several of the applications bundled with Django use this trick to do various things:
* django.contrib.sites listens to find out when its been installed, and creates the default “example.com” site object, which is needed for the admin to function.
* django.contrib.contenttypes listens for any new apps being installed, and creates new ContentType instances for all the models being installed.
* django.contrib.auth listens on two fronts: when the auth app is installed, it prompts you to create a superuser, and when any new app is installed, it creates permissions for that apps models.
This works because the syncdb function in manage.py imports the management files from all the installed and soon-to-be-installed apps in your project; that makes sure any app which needs to can take advantage of the dispatcher.
===== Other useful conventions =====
Of course, that doesnt cover all the things you might want to do within Django, so naturally people end up wondering how they should organize the rest of their code. Generally theres no need to require standardized layouts or locations for certain functions, but it can be helpful to adhere to a few conventions. So to provide an example, heres how I generally lay out any additional bits I need in things that Im working on.
At the project level, I generally dont add a whole lot; its rare that I need to do something that doesnt make more sense as part of an application. However, if youre going to be running multiple projects which all use some or all of the same applications, it can be useful to organize your settings carefully. Jacob has, once or twice, pointed out the trick that we use at the Journal-World, and I think its fairly useful:
//we have our code base in one directory structure, and settings files in another, with a “default” settings file at the top level of the settings tree. Settings files for individual sites import the default settings and override anything they need to, or add any extra settings they require. Because Django doesnt require settings files to live in the same directory tree as the applications their projects use, this is extremely easy and extremely useful to do.//
At the application level, I usually drop in **a few more** files depending on exactly what the application is going to be using:
* If the application defines any custom manipulators, I put them in a file called __forms.py __instead of in the views file.
* If there are multiple custom managers in the app, I put them in a file called __managers.py__ instead of the models file.
* If Im defining any custom context processors, I put them in a file called __context_processors.py__.
* If Im setting up any custom dispatcher signals, they go in a file called __signals.py__.
* If the application is setting up any syndication feeds, the feed classes go in a file called __feeds.py__. Similarly, sitemap classes go in __sitemaps.py__.
* Middleware classes go in a file called __middleware.py__.
* Any miscellaneous code which doesnt clearly go anywhere else goes in a file or module called __utils__.
I dont always use all of that functionality in an app, but if I do its nice to have a convention for it, so that I only need to remember to do from appname import forms or from appname import feeds.
===== And one more thing… =====
This is something Im still in the process of developing, but I also like to have an easy way to test the **dependencies** my applications have, and to make sure everything is **configured** properly. The easiest way to do this, in my experience, is to put some code in the applications__ __init__.py__ which checks for everything the application will need. I wrote up a simple example in a post on the Django developers list, and Im still working on improving that; there are functions tucked away in django.core.management which will let you test not only whether an application can be imported and is listed in the INSTALLED_APPS setting, but whether its actually been installed into the database.
===== How do you do it? =====
I think Ive covered everything I know of, and every trick I use, for laying out a Django project or application cleanly; if you see something here you like, feel free to start using it. And if Ive overlooked something cool that you know of, please post it in a comment and let the world know about it :)

View File

@@ -0,0 +1,373 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T10:17:36+08:00
====== Django 最佳实践 - 中文版 (2009-06-17) ======
Created Sunday 23 October 2011
http://yangyubo.com/django-best-practices/
===== 译者 (yospaly) 前言 =====
Django 最佳实践 (django-best-practices) 是 django-reusable-app-docs 的一个分支项目, 它在原有项目的理念上进行了扩展, 建立了一套关于 Django Web 开发方面的 “最佳实践” 规则, 这些理念超出了官方文档的讨论范围.
这份文档由一系列准则组成, 围绕这如何创建便于维护, 代码干净, 结构清晰, 方便复用, 易于部署的 Django 项目. 对于初学者, 它是一份不可多得指南, 如果不知道从何下手, 按照文档说做能很快规范起来; 对于经验丰富 Django 达人, 它也有一定的参考价值, 可以据此来创建自己的最佳实践准则.
遗憾的是本人理工科出身, 水平有限, 翻译中规中矩, 只能勉强表达出原文传递的信息. 还有小部分尚不解其意 (文中有备注) :)
原文是多页面方式, 不过 实践 每个规则的内容并不太多, 打散成多页面反而浏览不方便. 所以我把它们全合并到单个页面中, 除此之外, 没做其它改动.
原文和译文的源文件均使用 reStructuredText 格式, 可以用 Sphinx 转换成 HTML 等格式的文档.
====== Django 最佳实践 ======
这是一份关于开发和部署** Django Web 框架** 的动态文档 (会随时更新). 这些准则不应该被认为是 绝对正确 或 唯一 使用 Django 的方法, 应该说这些最佳实践是我们使用框架多年来积累的经验.
本项目是 django-reusable-app-docs 项目 的一个分支, 这个优秀的项目是由 Brian Rosner 和 Eric Holscher 建立的, 是关于如何开发和维护可复用 Django apps 方面的最佳实践准则.
===== 代码风格 =====
一般而言, 代码应该干净, 简明, 易读. The Zen of Python (PEP 20) 是 Python 编码实践的权威介绍.
* 尽可能合理的遵守 Style Guide for Python Code (PEP 8).
* 遵守 Django coding style.
Django 应用 (app)
如何发布我的 app ?
Django 应该使用使用标准的 Python Package Index 即 Pypi 和 Cheese Shop. 我写过一篇关于如何轻松打包和上传 app 到 Pypi 的 教程.
如果你上传 app 到 Pypi, 建议最好在你的项目名前加上 “django-” 前缀.
(yospaly: 以下不解其意, 望达人指点) Also note, that when below when we refer to the default place for something as a file, that also means that you can make a directory of that same name; as per normal python.
文档
放在和 APP 目录同级的 docs 目录中 (你的 app 应该有上级目录的吧?)
可以包含模板, 供使用者参考
什么是可复用 app?
一个 Django app, 一个能够轻松嵌入到 project 的 app, 提供一个非常明确的功能. 它们应该专注并遵循 Unix 哲学 “做一件事并把它做好”. 更多相关信息请参考 James Bennett 的 Djangocon talk.
Application 模块
(yospaly: 以下所有大写单词, 如: APP, MODEL 等, 替换成你项目中真实的 app 名或 model 名.)
Admin
非必须
放在 APP/admin.py 文件中
Admin 的 MODEL 类命名为 MODELAdmin
上下文处理器
放在 APP/context_processors.py 文件中
内容源
放在 APP/feeds.py 文件中
表单
放在 APP/forms.py 文件中
Managers
放在 APP/managers.py 文件中
中间件
放在 APP/middleware.py 文件中
实现尽可能少的任务
模型
放在 APP/models (.py 文件中或目录下)
遵循 Djangos 模型约定
模板
放在 APP/templates/APP/template.html 文件中
为了尽量标准化 Django 模板区块 (block) 名称, 我建议通常情况下使用以下区块名称.
{% block title %}
这个区块用来定义页面的标题. 你的 base.html 模板很可能要在这个 tag 之外定义站点名字 (Sites name) (即便使用了 Sites 框架), 以便能够放在所有页面中.
{% block extra_head %}
我认为这是个非常有用的区块, 很多人已经以某种方式在使用了. 很多页面经常需要在 HTML 文档头添加些信息, 比如 RSS 源, Javascript, CSS, 以及别的应该放在文档头的信息. 你可以, 也很可能将会, 定义另外专门的区块 (比如前面的 title 区块) 来添加文档头的其它部分的信息.
{% block body %}
这个 tag 用来包含页面的整个 body 部分. 这使得你在 app 中创建的页面能够替换整个页面内容, 不仅仅是正文内容. 这种做法虽不常见, 但当你需要时, 它确实是一个非常方便的 tag. 你可能还没注意到, 我一直尽可能的使 tag 名字和 HTML 标签名称保持一致.
{% block menu %}
你的菜单 (导航栏) 应该包含在这个区块中. 它是针对站点级的导航, 不是每个页面专属的导航菜单.
{% block content %}
这个区块用来放置页面正文内容. 任何页面正文内容都可能不一样. 它不包含任何站点导航, 信息头, 页脚, 或其它任何属于 base 模板的东东.
其它可能的区块
{% block content_title %}
用来指定 content 区块的 “title”. 比如 blog 的标题. 也可以用来包含 content 内的导航 (译注: 比如提纲), 或其它类似的东东. 大致都是些页面中并非主要内容的东东. 我不知道这个区块是否应该放到 content tag 内, 并且对应于前面建议的 content tag, 是不是还需要一个 main_content 区块.
{% block header %} {% block footer %}
任何每个页面都可能修改的文本区域的页面和页脚.
{% block body_id %} {% block body_class %}
用来设置 HTML 文档 body 标签的 class 或 id 属性. 在设置样式或其它属性时非常有用.
{% block [section]_menu %} {% block page_menu %}
这是对应于之前建议的 menu 区块. 用来导航一个章节或页面.
模板标签
放在 APP/templatetags/APP_tags.py 文件中
推荐的模板标签语法
as (Context Var): This is used to set a variable in the context of the page
for (object or app.model): This is used to designate an object for an action to be taken on.
limit (num): This is used to limit a result to a certain number of results.
exclude (object or pk): The same as for, but is used to exclude things of that type.
测试
放在 APP/tests (.py 文件或目录) 中
Fixtures 放在 APP/fixtures/fixture.json 文件中
通常只须重写 Django 的 testcase
URLs
放在 APP/urls (.py 文件或目录) 中
需要设置 name 属性以便能够被反查; name 属性设置成 APP_MODEL_VIEW 的格式, 比如 blog_post_detail 或 blog_post_list.
视图
放在 APP/views (.py 文件或目录) 中
可以是任何可调用的 python 函数.
视图参数应提供合理的缺省值, 并易于定制:
范例:
def register(request, success_url=None,
form_class=RegistrationForm
template_name='registration/registration_form.html',
extra_context=None):
Django Projects (项目)
推荐的布局
example.com/
README
settings.py
urls.py
docs/
This will hold the documentation for your project
static/
-In production this will be the root of your MEDIA_URL
css/
js/
images/
tests/
- Project level tests (Each app should also have tests)
uploads/
- content imgs, etc
templates/
- This area is used to override templates from your reusable apps
flatpages/
comments/
example/
app1/
app2/
什么是 Django Project?
Django 中的 project 指的是一个包含设置文件, urls 链接, 以及一些 Django Apps 集合的简单结构. 这些东东可以是你自己写的, 也可以是一些包含在你的 project 内的第三方代码.
Project 模块
设置
放在 [PROJECT]/settings.py 文件中
使用相对路径
import os
DIRNAME = os.path.dirname(__file__)
MEDIA_ROOT = os.path.join(DIRNAME, 'static')
具体环境相关的设置使用 local_settings.py 文件, 并在 settings.py 文件结尾导入它.
try:
from local_settings import *
except ImportError:
pass
URLs
放在 PROJECT/urls.py 文件中
应包含最少的逻辑代码, 多数情况下只作为一个指针, 指向你 apps 各自的 URL 配置.
部署
Project 的环境初始化
文件系统布局
Note
本文档严重偏向 Unix 风格的文件系统, 要在其它操作系统上使用需要做些额外的修改.
Virtualenv 对于 Python 项目来说是必须的. 它提供一个隔离不同 Python 运行环境的方法. 典型的, 我们在 /opt/webapps/<site_name> 部署生产环境站点, 在 ~/webapps/<site_name> 目录部署我们的开发环境站点. 每个 project 有它自己的 virtualenv, virtualenv 还充当 project 所有相关代码的根目录. 我们使用 pip 为 virtualenv 添加必要的包.
引导过程看上去是这样的:
cd /opt/webapps
virtualenv mysite.com
cd mysite.com
pip install -E . -r path/to/requirements.txt
source bin/activate
Tip
方便起见, 你可以在你的 virtualenv 根目录中创建 Django project 的符号链接. 符号链接的名字无所谓, 因为你的 project 已经在 Python 搜索路径中. 通过给你所有的 projects 起同样的符号链接名, 你可以使用一些 方便的 bash 函数以节省时间.
打包
成功部署的关键之一是, 保证你开发环境下的软件尽可能接近部署环境下的软件. Pip 提供了一个简单的重现方法, 让你在任何系统上都能非常一致的部署 Python 项目. 任何需要第三方库的 app 都应该包含一个名为 requirements.txt 的 pip 规格文件. Projects 应到负责汇集所有 app 的规格文件, 并在根据需要添加其它规格.
你的规格文件中要包含些什么
我们的经验是, 任何应用程序, 只要你的操作系统默认没附带. 唯一需要从我们的规格文件中剔除的几个包是 PIL, 数据库驱动和其它 pip 不能安装的包. 这些被剔除的规格放在 projects README 文件中加以说明.
服务器
Note
部署架构很大程度上取决于站点的流量. 下面描述的设置对我们来说, 在大多数情况下工作的最好.
我们基于 Linux 和 PostgreSQL 后端数据库部署 Django, Nginx 进程作为前端代理, 处在其后的是 Apache 和 mod_wsgi.
Nginx
Nginx 是一个非常优秀的前端服务器, 速度快, 稳如磐石, 并且资源占用很少. 以下是一个典型的 Nginx 站点配置:
# Apache server
upstream django {
server domain.com:9000;
}
# Redirect all requests on the www subdomain to the root domain
server {
listen 80;
server_name www.domain.com;
rewrite ^/(.*) http://domain.com/$1 permanent;
}
# Serve static files and redirect any other request to Apache
server {
listen 80;
server_name domain.com;
root /var/www/domain.com/;
access_log /var/log/nginx/domain.com.access.log;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
if (!-f $request_filename) {
proxy_pass http://django;
}
}
它都做些什么?
第一段告诉 Nginx 去哪里找托管了 Django 站点的服务器. 第二段把所有来自 www.domain.com 的请求重定向到 domain.com, 这样所有资源就都只有一个 URL 能被访问到. 最后一段承担了所有工作. 它告诉 Nginx 检查 /var/www/domain.com 中是否存在被请求的文件. 如果存在, 它返回该文件, 否则, 它将把请求转发给 Django 站点.
Warning
yospaly 注
以下涉及 Apache 的部分均未作翻译, 我们强烈建议使用 Nginx/Lighttpd + SCGI/FastCGI/HTTP 的方式, 尽量不要使用繁琐的 Apache + mod_wsgi.
SSL
Another benefit to running a frontend server is lightweight SSL proxying. Rather than having two Django instances running for SSL and non-SSL access, we can have Nginx act as the gatekeeper redirecting all requests back to a single non-SSL Apache instance listening on the localhost. Heres what that would look like:
server {
listen 67.207.128.83:443; #replace with your own ip address
server_name domain.com;
root /var/www/domain.com/;
access_log /var/log/nginx/domain.com.access.log;
ssl on;
ssl_certificate /etc/nginx/ssl/certs/domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/private/domain.com.key;
ssl_prefer_server_ciphers on;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Protocol https;
if (!-f $request_filename) {
proxy_pass http://django;
}
}
You can include this code at the bottom of your non-SSL configuration file.
Tip
For SSL-aware Django sites like Satchmo, youll need to “trick” the site into thinking incoming requests are coming in via SSL, but this is simple enough to do with a small addition to the WSGI script we discuss below.
Apache
We run the Apache2 Worker MPM with mod_wsgi in daemon mode. The default settings for the MPM Worker module should be sufficient for most environments although those with a shortage of RAM may want to look into reducing the number of servers spawned. Since Nginx will be listening for HTTP(S) requests, youll need to bind Apache to a different port. While youre at it, you can tell it to only respond to the localhost. To do so, youll want to edit the Listen directive
Listen 127.0.0.1:9000
With Apache up and running, youll need an Apache configuration and WSGI script for each site. A typical Apache configuration for an individual site looks like this:
<VirtualHost *:9000>
ServerName domain.com
ServerAdmin webmaster@domain.com
ErrorLog /var/log/apache2/domain.com.log
WSGIDaemonProcess domain display-name=%{GROUP} maximum-requests=10000
WSGIProcessGroup domain
WSGIScriptAlias / /opt/webapps/domain.com/apache/django.wsgi
<Directory /opt/webapps/domain.com/apache>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
Tip
In a perfect world, your app would never leak memory and you can leave out the maximum-requests directive. In our experience, setting this to a high number is nice to keep Apaches memory usage in check.
Warning
This will default to a single process with 15 threads. Django is not “officially” thread safe and some external libraries (notably a couple required for django.contrib.gis) are known to not be thread safe. If needed the threads and processes arguments can be adjusted accordingly.
It links to the WSGI script within the project directory. The script is just a few lines of Python to properly setup our environment.
import os, sys
import site
# put virtualenv on pythonpath
site.addsitedir('/opt/webapps/domain.com/lib/python2.5/site-packages')
# redirect print statements to apache log
sys.stdout = sys.stderr
os.environ['DJANGO_SETTINGS_MODULE'] = 'domain.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

View File

@@ -0,0 +1,131 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T20:17:13+08:00
====== Django使用Uploadify组件实现图片上传 ======
Created Sunday 23 October 2011
http://2goo.info/blog/panjj/Django/2011/08/04/527
Uploadify组件上传文件很酷可以实现文件进度上传而且可以批量上传各种文件。好处还很多具体详情登到官网看看文档了解吧。在同类组件中Uploadify做的也很出色。打算在Django中用它两个东西结合使用也算简单但有些细节需要记下来以便以后重用。
这次只说上传图片部分至于上传文件其实可以照猫画虎而且来得会简单些只是python程序后端写法的区别而已前端代码Uploadify一律平等对待图片也是文件一种特例罢了。
Django使用Uploadify组件实现图片上传可以分为两个大步骤。
前端引用Uploadify所需要的类库(javascript)和脚本样式(css)。
Uploadify会用到JQuery类库还有自己的几个脚本和样式文件搭配好了Django的静态文件让Django**正确解析静态文件**就算成功一半了静态文件的配置参考先前的博客《Django静态文件的配置》。
静态文件我们统一存放在根目录的**site_media**文件夹下到官网http://www.uploadify.com/下载Uploadify-2.14组件放在site_media下的**plugin**随意起名uploadify_214再新建个文件夹**upload(位于site_media下)**,来存放上传的图片。
前端样式脚本引用代码:
<link href="/site_media/plugin/uploadify_214/uploadify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="/site_media/js/jquery.js"></script>
<script type="text/javascript" src="/site_media/plugin/uploadify_214/swfobject.js"></script>
<script type="text/javascript" src="/site_media/plugin/uploadify_214/jquery.uploadify.v2.1.4.min.js"></script>
引用文件的路径算是很重要具体静态配置决定这些。首先引用Uploadify的样式文件然后就是先引用JQuery类库再引用Uploadify自身脚本swfobject.js和jquery.uploadify.v2.1.4.min.js
Uploadify组件初始化代码放在包含上传功能的模板文件里
<script type="text/javascript">
$(document).ready(function() {
$('#file_upload').uploadify({
'uploader' : '/site_media/plugin/uploadify_214/uploadify.swf',
'script' : '{%url uploadify_script%}',
'cancelImg' : '/site_media/plugin/uploadify_214/cancel.png',
'folder' : '/upload',
'auto' : false,//
'multi': true,//设置可以上传多个文件
'queueSizeLimit':20,//设置可以同时20个文件
'removeCompleted':false,//
'sizeLimit':10240000,//设置上传文件大小单位kb
'fileExt':'*.jpg;*.gif;*.png',//设置上传文件类型为常用图片格式
'fileDesc':'Image Files',
'onInit': function () {},
'onError' : function (event,ID,fileObj,errorObj) {
$('#id_span_msg').html("上传失败,错误码:"+errorObj.type+" "+errorObj.info);
},
'onSelect': function (e, queueId, fileObj) {
$('#id_span_msg').html("");
},
'onAllComplete': function (event, data) {
if(data.filesUploaded>=1){
$('#id_span_msg').html("上传成功!");
}
}
});
});
</script>
初始化脚本,有几个关键的参数需要说明一下:
uploader是组件需要flash编译文件里面封装了Uploadify核心的处理程序。
script是后端上传文件程序的url这个是后面说的需要自己写。
folder是上传文件的目录这里我们不计划使用它随便写一个充数。
前端html代码
<h1>Uploadify组件上传方式</h1>
<div class="demo-box">
<input id="file_upload" type="file" name="Filedata">
<div id="file_uploadQueue" class="uploadifyQueue"></div>
<p><a href="javascript:$('#file_upload').uploadifyUpload()">上传图片</a>
<a href="javascript:$('#file_upload').uploadifyClearQueue()">取消上传</a>
</p>
<p><span id="id_span_msg"></span></p>
</div>
二:写好后端图片上传的方法。
如果刚开始就把写好的上传程序和Uploadify结合也许不是很明智的做法因为过程中遇到问题我们不很确定是后端程序的bug还是Uploadify的配置错误所以建议先把写好的后端上传程序用传统的上传方式去测试把程序调试好了再和Uploadify结合这样就会很清楚是那块出现问题了。
所以我们先写个通用的上传函数_upload用传统的上传方式测试它该函数
def _upload(file):
'''图片上传函数'''
if file:
path=os.path.join(**settings.MEDIA_ROOT,'upload'**)
file_name=str(**uuid.uuid1()**)+".jpg"
path_file=os.path.join(path,file_name)
parser = ImageFile.Parser()
for chunk in file.chunks():
parser.feed(chunk)
img = parser.close()
try:
if img.mode != "RGB":
img = img.convert("RGB")
img.save(path_file, 'jpeg',quality=100)
except:
return False
return True
return False
这个程序接收一个Files对象在内存里处理保存好图片程序就几行代码就不解释太多了。大体是先构造一个物理地址用于保存图片再把内存里的图片信息存入img临时变量中判断图片的模式如果不是RGB转换保存成jpg格式返回True失败返回False。
该函数测试通过了能完成保存图片的使命最后就是写Uploadify需要的函数uploadify_script
@csrf_exempt
def uploadify_script(request):
response=HttpResponse()
response['Content-Type']="text/javascript"
ret="0"
file = request.FILES.get("Filedata",None)
if file:
if _upload(file):
ret="1"
ret="2"
response.write(ret)
return response
Uploadify使用uploadify_script函数通过Get方式把图片控件的信息提交给该函数函数返回"text/javascript"的内容类型如果成功写入字符1否则写入非1字符。页面的图片控件命名FiledataDjango通过file = request.FILES.get("Filedata",None)获取控件的图片信息如果不是空的就传递给刚才说的通用函数_upload保存图片。
整个过程算是完结了,过程中值得注意的:
1 常常出现IO Error如果我们已经测试_upload和uploadify_script后端程序他们都没有错误很多程度上是因为前端的Uploadify初始化脚本的问题确认Uploadify几个关键的参数能不能正确解析或者是静态文件配置没成功造成的。
2 Forbidden (403)这是Django引发的Django1.3引进了CSRF我们需要进行一些处理给uploadify_script一个装饰器@csrf_exempt记住这个很关键很折腾人。
3 cannot write mode P as JPEG这个是后端上传程序的错误是因为上传了非jpg类型的图片我们需要需要转换成RGB再保存上面已经提过。
好了不废话,例行给一个例子,看源码就明白了,本地浏览地址http://127.0.0.1:8000/uploadify/。

View File

@@ -0,0 +1,77 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T20:52:38+08:00
====== Django标准化项目dj-scaffold ======
Created Sunday 23 October 2011
http://haoluobo.com/2011/08/dj-scaffold/
由于Django没有象rails一样指定项目的目录结构规范很多人都对django项目的目录结构要如何组织而感到困惑。为此我又新创建了一个开源项目dj-scaffolddjango的脚手架。这个项目用于自动生成一个标注化的django项目和app目录结构同时提供虚拟化环境。
项目地址https://github.com/vicalloy/dj-scaffold
===== 安装 =====
已经发布到了pypi所以你可以用pip或easy_install 来进行安装。
pip install dj-scaffold 或
easy_install dj-scaffold
===== 使用 =====
dj-scaffold主要提供了两个命令dj-scaffold.py和lbstartapp。
====== dj-scaffold.py ======
该脚本用于取代django的startproject命令。使用方式如下
**dj-scaffold.py projectname **
在该命令执行后将创建项目projectname。在项目的scripts目录中提供了脚本create_env.py和env.rc。
* create_env.py 执行该脚本将__自动初始化并创建python虚拟环境__。新生成的python虚拟环境在env目录。
* env.rc 该脚本用户启动python虚拟环境source env.rc。该脚本同时为python manage.py设置了快捷方式__$mg__。你可以在任何目录调用$mg来执行django命令。比如你用$mg runserver来启动测试服务器。
项目对应的目录结构如下:
注:文件太多,去掉了部分不重要的文件
dj-scaffold.py projectname
|+docs/ #用于存放项目的相关文档
|+env/ #python虚拟环境由脚本自动生成
|~requirements/ #第三方依赖包的存放位置
| `-requirements.pip #pip的依赖说明文件
|~scripts/ #系统相关的脚本
| |-create_env.py ** #**__创建__**python虚拟环境env目录**
| `-env.rc #__进入__python虚拟环境。同时提供python manger.py的快捷方式$mg。可在任意目录使用$mg, 若要退出虚拟环境则可以使用deactive命令。
|~sites/ #Django的__项目目录__。在settings文件中增加了部分默认配置。如数据库默认使用sqlite设置项目的模板以及静态文件目录。
| |+media/ #项目静态文件(用户上传)
| |+static/ #项目静态文件css、js等
| `+templates/ #__项目模板__
|+tools/ #一些项目依赖的第三方工具包。如python虚拟环境初始化脚本等。
`~wsgi/ #项目部署用的wsgi文件
`-dj_scaffold.wsgi
====== lbstartapp ======
lbstartapp作为django的扩展命令提供。将dj_scaffold加到INSTALLED_APPS后即可使用该命令。该命令将生成一个标准的app相比django自带的startapplbstartapp将那些不太常用的app默认目录也都给生成了出来。对应目录结构如下
|+management/ #命令目录
|+static/ #静态文件目录
|+templates/ #模板目录
|+templatetags/ #tag目录
|-__init__.py
|-admin.py #admin管理后台的models配置文件
|-forms.py
|-models.py
|-settings.py #app自己的settings文件
|-tests.py
|-urls.py #urls配置文件
`-views.py
NOTE
项目的大多代码来自https://github.com/lincolnloop/django-startproject
类似项目https://github.com/mozilla/playdoh 个人觉得这个项目还可以。不过我个人觉得自己写的更符合自己的习惯。
“摒弃魔法”是Django的哲学之一。为此Django没有为用户提供太多的默认操作它希望一切对用户都是显示可见的。这本没太大的问题但在我看来“no magic”并不代表连规范都不要。Django实在是太缺乏一些必要的规范。

View File

@@ -0,0 +1,86 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T19:33:37+08:00
====== Django环境搭建常用的工具及做法 ======
Created Sunday 23 October 2011
http://2goo.info/blog/panjj/Django/2011/06/05/521
自己购买了个廉价的vps部署Django开发的网站汲取强大互联网的信息结合自己需要的环境尝试去搭配从中把最常用的工具和命令记录下来。服务器我选择Debian觉它更适合自己。Debian自带主流版本的Python最先要安装的是easy_install 和pip因为这两个工具可以方便安装python所需要的类库。
===== 安装方法: =====
apt-get install python-pip
pip install easy_install
pip install -U virtualenv
我们只需要给python安装**基本的类库**即可比如上面的pip easy_install和virtualenv等即可其他和django项目紧密相关的而因django项目不同而不用的类库我们**采用virtualenv工具具体安装就好了(这会将django项目的python环境和本机上的python环境隔离在virtualenv中安装的软件包不会带到本机中)**,比如:Django psycopg MySQLdb simplejson python-openid flup html5lib simplejson等。这样的做的好处很多这些类库版本都不断更新我们具体的项目具体安装具体的版本而**不会影响全局的python环境**把他们都集中在一个项目中。而且可以使用pip把这些虚拟环境的**类库清单**生成一个txt文件然后再通过pip一键式安装到位。
开始我们的环境搭建之旅吧。我们创建一个django虚拟环境
virtualenv --no-site-packages --distribute twogoo
cd twogoo
source bin/activate
此时已经进入虚拟环境接下来就是使用pip或者easy_install安装**项目的类库**了,如:
pip install django
pip install psycopg
pip install flup
...
我们目前在**项目环境文件夹**twogoo下当下建立**项目程序文件夹**myproject
django-admin.pu createproject myproject
我们已经安装了flup如果要启动fastcgi在虚拟环境中启动想要的端口9090或者其他的即可
python myproject/manage.py runfcgi method=threaded host=127.0.0.1 port=9090
启动了fastcgi如果我们修改了程序想再重启使用以上的命令是无效的我们需要关闭掉9090端口再重新启动
python myproject/manage.py runfcgi method=threaded host=127.0.0.1 port=9090
查看端口的PID,关闭掉端口的办法:
netstat -anp|grep 9090 #(端口号)
这时PID会列举出来比如PID是8920我们kill掉它
kill 8920
刚才说通过pip**一键式安装虚拟环境**,办法是先导出环境的**类库列表(除了python自带的标准库以外的安装)**
pip freeze > req.txt
这时会生成req.txt文件里面是具体的类库名和版本号格式如下
Django==1.3
Markdown==2.0.3
PIL==1.1.7
South==0.7.3
distribute==0.6.15
django-debug-toolbar==0.8.5
flup==1.0.3.dev-20110405
html5lib==0.90
psycopg2==2.4.1
python-openid==2.2.5
simplejson==2.1.6
wsgiref==0.1.2
我们再**根据req.txt文件创建一个wow项目虚拟环境**
cd ../
pip install -E wow -r twogoo/req.txt
此时会创建一个wow文件夹里面和twogoo环境是一模一样的。
如果要退出虚拟环境,请使用:
deactivate

View File

@@ -0,0 +1,169 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T20:42:04+08:00
====== Python virtualenv ======
Created Sunday 23 October 2011
http://www.rainsts.net/article.asp?id=1004
virtualenv 的作用相当于 Sandbox它通过隔离包目录和系统环境参数来实现多个**相对独立的虚拟环境**。如此可避免过多的第三方库因版本依赖造成问题。同时每个独立的虚拟环境只需通过打包即可分发,也大大方便了系统部署。
$ sudo easy_install virtualenv
现在我们可以创建虚拟环境了。
$ virtualenv test1
New python executable in test1/bin/python
Installing setuptools............done.
我们可以看到虚拟目录下已经被安装了基本所需的运行环境。
$ ls test1/bin
activate activate_this.py easy_install easy_install-2.6 pip python
$ ls test1/include/
python2.6
$ ls test1/lib
python2.6
$ ls test1/lib/python2.6/
_abcoll.py copy_reg.pyc linecache.py os.pyc sre_compile.py stat.py
_abcoll.pyc distutils linecache.pyc posixpath.py sre_compile.pyc stat.pyc
abc.py encodings locale.py posixpath.pyc sre_constants.py types.py
abc.pyc fnmatch.py locale.pyc re.py sre_constants.pyc types.pyc
codecs.py fnmatch.pyc ntpath.py re.pyc sre_parse.py UserDict.py
codecs.pyc genericpath.py ntpath.pyc site-packages sre_parse.pyc UserDict.pyc
config genericpath.pyc orig-prefix.txt site.py sre.py warnings.py
copy_reg.py lib-dynload os.py site.pyc sre.pyc warnings.pyc
进入 test1 目录,**激活虚拟环境。**
$ cd test1
test1$ source bin/activate
(test)test1$ which python
/home/yuhen/projects/test1/bin/python
(test)test1$ which easy_install
/home/yuhen/projects/test1/bin/easy_install
(test1)test1$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['',
'/home/yuhen/projects/test1/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg',
'/home/yuhen/projects/test1/lib/python2.6/site-packages/pip-0.7.2-py2.6.egg',
'/home/yuhen/projects/test1/lib/python2.6',
'/home/yuhen/projects/test1/lib/python2.6/plat-linux2',
'/home/yuhen/projects/test1/lib/python2.6/lib-tk',
'/home/yuhen/projects/test1/lib/python2.6/lib-old',
'/home/yuhen/projects/test1/lib/python2.6/lib-dynload',
'/usr/lib/python2.6',
'/usr/lib64/python2.6',
'/usr/lib/python2.6/plat-linux2',
'/usr/lib/python2.6/lib-tk',
'/usr/lib64/python2.6/lib-tk',
'/home/yuhen/projects/test1/lib/python2.6/site-packages',
'/usr/local/lib/python2.6/dist-packages/virtualenv-1.4.9-py2.6.egg',
'/usr/local/lib/python2.6/dist-packages/simplejson-2.1.1-py2.6-linux-x86_64.egg',
'/usr/local/lib/python2.6/site-packages',
'/usr/local/lib/python2.6/dist-packages',
'/usr/lib/python2.6/dist-packages',
'/usr/lib/pymodules/python2.6',
'/usr/lib/pymodules/python2.6/gtk-2.0',
'/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode']
>>>
可以看到使用 "souce bin/active" 激活以后,命令提示行多了一个** "(test1)" 前缀**,同时 python 和 easy_install 默认会使用虚拟环境 bin 目录下的程序。sys.path 显示当前虚拟环境的库目录被添加到搜索路径列表中。
(test1)$ easy_install MySQL-python
Searching for MySQL-python
Reading http://pypi.python.org/simple/MySQL-python/
Reading http://sourceforge.net/projects/mysql-python
Best match: MySQL-python 1.2.3c1
Downloading http://sourceforge.net/.../1.2.3c1/MySQL-python-1.2.3c1.tar.gz/download
Processing download
Running MySQL-python-1.2.3c1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-Em0wfb/MySQL-python-1.2.3c1/egg-dist-tmp-vzoJ2t
In file included from _mysql.c:36:
/usr/include/mysql/my_config.h:1050:1: warning: "HAVE_WCSCOLL" redefined
In file included from /usr/include/python2.6/Python.h:8,
from pymemcompat.h:10,
from _mysql.c:29:
/usr/include/python2.6/pyconfig.h:808:1: warning: this is the location of the previous definition
zip_safe flag not set; analyzing archive contents...
Adding MySQL-python 1.2.3c1 to easy-install.pth file
Installed /home/yuhen/projects/python/test1/lib/python2.6/site-packages/MySQL_python-1.2.3c1-py2.6-linux-x86_64.egg
Processing dependencies for MySQL-python
Finished processing dependencies for MySQL-python
(test1)$ ls -l lib/python2.6/site-packages/
total 444
-rw-r--r-- 1 yuhen yuhen 283 2010-06-02 09:46 easy-install.pth
-rw-r--r-- 1 yuhen yuhen 106325 2010-06-02 09:46 MySQL_python-1.2.3c1-py2.6-linux-x86_64.egg
drwxr-xr-x 4 yuhen yuhen 4096 2010-06-02 09:45 pip-0.7.2-py2.6.egg
-rw-r--r-- 1 yuhen yuhen 333447 2010-06-01 23:58 setuptools-0.6c11-py2.6.egg
-rw-r--r-- 1 yuhen yuhen 30 2010-06-02 09:45 setuptools.pth
(test1)$ cat lib/python2.6/site-packages/setuptools.pth
./setuptools-0.6c11-py2.6.egg
(test1)$ python
>>> import MySQLdb
>>> MySQLdb.version_info
(1, 2, 3, 'gamma', 1)
>>>
MySQL-python 被安装到了虚拟环境中,且 easy-install.pth 中正确添加了 egg 搜索路径。
最后我们可以用 "deactivate" 命令**退出虚拟环境**。
(test1)test1$ deactivate
在创建虚拟环境时,我们可以添加 "--no-site-packages" 参数指示虚拟环境不要访问 global site-packages。
$ virtualenv --no-site-packages test2
New python executable in test2/bin/python
Installing setuptools............done.
$ cd test2
test2$ source bin/activate
(test2)test2$ python
>>> import sys
>>> sys.path
['',
'/home/yuhen/projects/python/test2/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg',
'/home/yuhen/projects/python/test2/lib/python2.6/site-packages/pip-0.7.2-py2.6.egg',
'/home/yuhen/projects/python/test2/lib/python2.6',
'/home/yuhen/projects/python/test2/lib/python2.6/plat-linux2',
'/home/yuhen/projects/python/test2/lib/python2.6/lib-tk',
'/home/yuhen/projects/python/test2/lib/python2.6/lib-old',
'/home/yuhen/projects/python/test2/lib/python2.6/lib-dynload',
'/usr/lib/python2.6',
'/usr/lib64/python2.6',
'/usr/lib/python2.6/plat-linux2',
'/usr/lib/python2.6/lib-tk',
'/usr/lib64/python2.6/lib-tk',
'/home/yuhen/projects/python/test2/lib/python2.6/site-packages']
>>>
搜索路径中除了 Python 基本库路径外,已经没有了 global site-packages。这样即便我们在安装了大量开发包的的系统里也可以隔离出一个干净的测试环境。
要判断一个虚拟环境是否 --no-site-packages除了检查 sys.path 外,还可以通过 "lib/python2.6/no-global-site-packages.txt" 文件来判断。

View File

@@ -0,0 +1,73 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T21:40:42+08:00
====== 发布一个Django的论坛系统LBForum开源、带演示 ======
Created Sunday 23 October 2011
http://haoluobo.com/2010/02/%E5%8F%91%E5%B8%83%E4%B8%80%E4%B8%AAdjango%E7%9A%84%E8%AE%BA%E5%9D%9B%E7%B3%BB%E7%BB%9Flbforum%EF%BC%88%E5%BC%80%E6%BA%90%E3%80%81%E5%B8%A6%E6%BC%94%E7%A4%BA%EF%BC%89/c
简介
LBForum 用django开发的论坛系统演示地址为http://vik.haoluobo.com/lbforum/
项目的地址为http://github.com/vicalloy/LBForum
界面部分抄的 FluxBB(一个开源的PHP论坛 http://fluxbb.org/ )。
虽然Django写的论坛也不少不过还真没什么好用的。
大多Django论坛都是独立的app而且不少还缺模板想我这样有经验的Django用户要跑起来都觉得麻烦其他普通用户就更别说了。
LBForum主要注重部署的方便性和易用性功能方面目前还比较简单。
LBForum一开始就是以整站的形式提供所以以LBForum做为基础项目进行二次开发是很容易的。
同时LBForum的开发尽量遵照Django可复用app原则因此即使需要将LBForum做为独立的app集成到其他项目也并不会太难。
主要功能
目前功能还比较简单,而且还有些小问题有待修正。
论坛分类,分版块
发帖,回帖
BBCode支持
置顶贴
使用django admin提供论坛管理功能
用开发服务器把LBForum跑起来
先把代码down下来。LBForum托管在github上http://github.com/vicalloy/LBForum 。如果你没有安装git你可以直接用界面右上方的download
source功能下载代码。
运行\scripts\create_lbforum_env.py初始化lbforum的python虚拟环境。该脚本会自动创建一个python的虚拟环境并使用easy_install安装对应的依赖包同时将一些依赖包解压到对应的目录中。
django使用的是svn版本所以机器上必须要安装有SVN不然脚本会运行失败。如果因为由于svn的问题导致脚本运行失败可以运行lbforum_env.bat进入lbforum环境手动安装django的svn版本。
环境初始化好后运行lbforum_env.bat进入lbforum环境
运行%mg% syncdb初始化数据库
运行%mg% runserver启动django开发服务器
进入admin创建论坛分类和版块
进入版块发帖
LBForum的目录结构说明
|+lbforum_env/#lbforum运行的python虚拟环境运行create_lbforum_env.py后自动创建
|+requirements/#lbforum用的第三方库和app运行的时候会将该目录加到python路径
|~scripts/#工程相关脚本
| |-create_lbforum_env.py#初始化python虚拟环境并自动安装easy_install/django依赖库
| |-helper.py#提供其他脚本所需的辅助函数
| `-lbforum_env.bat*#启动lbforum运行的虚拟环境及并为lbforum的manage.py提供快捷方式%mg%,比如初始化数据库%mg%
syncdb
|~sites/#站点配置/模板/静态文件
| `~default/#默认站点
| |+static/#静态资源文件如css等
| |+templates/#Django模板目录
| |+templates_plus/#Django模板目录用户将自己重写过的目标放到该目录
| `-……
|~src/#django的app目录
| |+account/#account相关app。具体站点通常会对用户中心进行定制所以该app在实际应用中很可能需要针对实际情况进行修改。
| |+djangohelper/#一些django的辅助函数等
| |+lbforum/#lbforum的主app论坛功能都在改app中
| |+lbregistration/#registration app的lbforum扩展主要去掉邮件地址认证功能
| |+onlineuser/#显示在线用户的app可复用的django app可脱离lbforum单独使用
| `+simpleavatar/#头像功能的app可复用的django app可脱离lbforum单独使用依赖djangohelper
|+tools/#工程用到的辅助工具目前只有一个virtualenv的脚本
注:
由于计划在以后做i18n所以目前只提供英文界面
django的错误提示是显示在字段后面fluxbb的错误全部都显示在表单前面。由于模板没有调好所以目前按照fluxbb的方式显示错误所以错误显示有些不太正常。
bbcode的输入框本想做成自适应大小的不过也调得有些问题所以现在输入框的大小固定。
文档… ,感觉好难写-_-,目前文档不全(项目中没有带任何的文档),日后补上。
应用程序的目录结构主要查看pinax
simpleavatar模块部分代码来自django-avatar
依赖包除用easy_install在线安装的外尽量使用zip包的方式附带在项目中减少安装依赖包的困难。
远程部署脚本计划使用fabric但fabric本身安装比较麻烦所暂未处理。
项目最早放在googlecode不过感觉github的功能更强些所以移了过去。

View File

@@ -0,0 +1,56 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T21:07:20+08:00
====== 合理的组织django的settings文件 ======
Created Sunday 23 October 2011
http://haoluobo.com/2011/10/django-settings/
django在一个项目的目录结构划分方面缺乏必要的规范因此不同人的项目组织形式也千奇百怪而且也很难说谁的做法就比较好。我根据自己的项目组织习惯发布了一个项目dj-scaffold。
前些天在reddit上为我的项目dj-scaffold打了个“广告”http://redd.it/kw5d4。不想评价甚糟甚至差点被打成负分。其中更也人将这个项目说的一文不值。面对负面声音虽然会有些不爽但其中的建设性意见还是需要听取的至于那些纯属个人偏好部分就自动过滤了。
在谈及settings文件如何组织时coderanger建议参考The Best (and Worst) of Django中的做法。文中的主要观点是开发环境和生产环境的配置都需要放到VCS中进行版本控制。参考文中的做法我对settings模块做了部分调整。注代码 https://github.com/vicalloy/dj-scaffold/tree/master/dj_scaffold/conf/prj/sites/settings
local_settings的弊病
为将项目的默认配置和本地配置区分开最常用的做法是增加一个local_settings.py文件并在settings文件的最后对该文件进行import。
try:
from local_settings import *
except:
pass
由此引发的问题是你不能对local_settings.py进行版本控制部署环境的配置万一丢失将难以找回。
解决方案
针对该问题,建议的解决方案如下
合理的配置文件组织方式
|~settings/
| |-__init__.py
| |-base.py #默认配置信息
| |-dev.py #开发环境的配置
| |-local.sample #本地的扩展配置在dev和production的最后进行import
| |-pre.sample #设置当前使用的配置为生产环境还是开发环境
| `-production.py #生产环境的配置
使用方式
DJANGO_SETTINGS_MODULE
django的admin脚本提供了settings参数用于指定当前使用的配置文件
django-admin.py shell --settings=settings.dev
在wsgi脚本中则可直接设置需要使用的settings
deploy.wsgi
os.environ['DJANGO_SETTINGS_MODULE'] = settings.production
简化参数
当然如果每次使用django-admin.py的时候都要带上settings参数还是非常恼人所以推荐的做法是在pre.py中配置自己所需要使用的配置文件。
SETTINGS = 'production' #dev

View File

@@ -0,0 +1,56 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T20:36:22+08:00
====== Django静态文件的配置 ======
Created Sunday 23 October 2011
http://2goo.info/blog/panjj/Django/2010/10/07/131
一直在寻找产品部署环境和开发环境时Django静态文件配置的差异化。比如说网站的css js和一些非程序相关的文件我暂时看成是静态文件。我们怎么正确配置才能让Django网站解析到静态文件呢简明来说要注意两个文件settings.py urls.py。
首先在settings文件中引用os模块
import os
然后我们定义一个常量,项目的**根目录地址**
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
再者就是给**MEDIA_ROOT**赋值为:
MEDIA_ROOT= os.path.join(PROJECT_PATH,'static')
注意我们的静态文件在根目录下的static文件里如果文件夹名不一样join的参数改成 自己起用的名字)
settings.py 配置完了urls.py呢如下配置
from django.conf import settings
url(r'^static/(?P<path>.*)$', 'django.views.static.serve',{'document_root': **settings.MEDIA_ROOT** },name="media"),
^static/(?P<path>.*)$的static可以随自己喜欢的名字建议参考Django最佳实践做法。也许urls配置很重要稍微不小心url经常解析不到真正的静态文件。之前喜欢使用media比如^media/(?P<path>.*)$结果老解析不到静态文件还瞎捣鼓MEDIA_ROOT终究还是没有解析成功后来把media改成static一下子成功了。注意不一定是static只要不是media应该就可以了。很奇怪不知道是不是Django其他地方用到media了比如Django的Admin。
最后就是如何在templates里使用静态文件了
<script type="javascript/text" **src="/static/js/config.js"**></script>
<link rel="stylesheet" type="text/css" href="/static/css/contents.css"/>
<img src="/static/images/logo.ipg" alt=""/>
使用的时候注意 路径的开头需要加上/
这样的配置,在开发环境中式能正常解析的,在**产品部署环境**中只需修改settings文件的
MEDIA_URL
ADMIN_MEDIA_PREFIX
把他们改成实际的域名
MEDIA_URL='http://www.XXX.com/static/'
ADMIN_MEDIA_PREFIX='http://www.XXX.com/static/admin/'
ADMIN_MEDIA_PREFIX后面的admn可能有点差异我们是把Django的admin**静态文件拷贝**到一个名叫admin(static/admin)的文件夹里的。
补充根据实际的实践中发现ADMIN_MEDIA_PREFIX如果指定了后缀media或者static比如ADMIN_MEDIA_PREFIX='http://www.XXX.com/media/'或者ADMIN_MEDIA_PREFIX='http://www.XXX.com/static/'
urls.py应该另起一个后缀比如
url(r'^site_media/(?P<path>.*)$','django.views.static.serve',{'document_root':settings.MEDIA_ROOT },name="site_media"),
我们指定了site_media作为后缀而没有采用media和static是**避免和后台的静态路径冲突**而我们应用的静态文件无法得到正常解析。
(完)

View File

@@ -0,0 +1,49 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-21T22:29:39+08:00
====== Django项目production环境发布笔记 ======
Created Friday 21 October 2011
这里使用apache2 + mod_python, 安装忽略, 另外需要到你部署的机子上安装django 和 MySQLdb我用的ubuntu server装上之后 apache2, mod_python, MySQLdb 都已经有了, 装个django就好了。
其实配置蛮简单的, 修改/etc/apache2/httpd.conf 加入以下片段。
Alias /site_media /home/denny/zoomino/website/zoomino_media
<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE zoomino.settings
# PythonOption django.root /
PythonDebug On
PythonPath "sys.path +['/home/denny']"
</Location>
<Location "/site_media">
SetHandler None
</Location>
项目位于/home/denny,这里要注意PythonPath 这里不是设置/home/denny/zoomino而且project dir的**上一级目录** 也就是你运行django-admin.py startproject的当前目录。如果你想在开发的时候自动定位你的template dir请看这篇文章http://dengyin2000.iteye.com/blog/323391。
django虽然把可以处理静态文件但是django内置的web server很差所以发布的时候需要用apache这样的handle。
Alias /site_media /home/denny/zoomino/website/zoomino_media 这句定义__资源文件的路径和映射的url__。
然后我们把django项目映射到根url“/”上。 因为我把django映射到了根上 所以最后一段肯定要加要不然资源文件会被django handle了那肯定是要报错的。
OK最后把settings.py的DEBUG设成False 重启apache就行了。
如何在开发的时候处理静态文件请看。 http://docs.djangoproject.com/en/dev/howto/static-files/#howto-static-files 再结合我的这篇文章http://dengyin2000.iteye.com/blog/323391定位你的static files就完美了。
参考http://docs.djangoproject.com/en/dev/topics/install/#database-installation
http://docs.djangoproject.com/en/dev/intro/install/#intro-install
http://docs.djangoproject.com/en/dev/howto/deployment/modpython/#howto-deployment-modpython
安装apache mod-python
http://www.howtoforge.com/embedding-python-in-apache2-with-mod_python-debian-ubuntu-fedora-centos-mandriva-opensuse

View File

@@ -0,0 +1,116 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-22T17:27:37+08:00
====== How to serve static files ======
Created Saturday 22 October 2011
https://docs.djangoproject.com/en/1.2/howto/static-files/
**Django itself doesnt serve static (media) files, such as images, style sheets, or video. It leaves that job to whichever Web server you choose.**
The reasoning here is that standard Web servers, such as Apache, lighttpd and Cherokee, are much more fine-tuned at serving static files than a Web application framework.
With that said, **Django does support static files during development**. You can use the__ django.views.static.serve() __view to serve media files.
== See also ==
If you just need to serve the admin media from a nonstandard location, see the **--adminmedia parameter to runserver**.
===== The big, fat disclaimer =====
Using this method is inefficient and insecure. Do not use this in a production setting. Use this** only for development.**
For information on serving static files in an Apache production environment, see the Django mod_python documentation.
===== How to do it =====
Heres the formal definition of the serve() view:
**def serve(request, path, document_root, show_indexes=False)**
To use it, just put this in your URLconf:
**(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',**
** {'document_root': '/path/to/media'}),**
...where__ site_media__ is the URL where your media will be rooted, and __/path/to/media__ is the filesystem root for your media. This will call the serve() view, passing in the path from the URLconf and the (required) __document_root __parameter.
Given the above URLconf:
The file /path/to/media/foo.jpg will be made available at the URL /site_media/foo.jpg.
The file /path/to/media/css/mystyles.css will be made available at the URL /site_media/css/mystyles.css.
The file /path/bar.jpg will not be accessible, because it doesn't fall under the document root.
Of course, it's not compulsory to use a fixed string for the 'document_root' value. You might wish to make that an entry in your settings file and use the setting value there. That will allow you and other developers working on the code to easily change the value as required. For example, if we have a line in __settings.py__ that says:
**STATIC_DOC_ROOT = '/path/to/media'**
...we could write the above URLconf entry as:
**from django.conf import settings**
**...**
**(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',**
** {'document_root': settings.STATIC_DOC_ROOT}),**
Be careful not to use the same path as your __ADMIN_MEDIA_PREFIX__ (which defaults to /media/) as this will overwrite your URLconf entry.
===== Directory listings =====
Optionally, you can pass the __show_indexes__ parameter to the serve() view. This is False by default. If it's True, Django will **display file listings** for directories.
For example:
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': '/path/to/media', 'show_indexes': True}),
You can customize the index view by creating a template called** static/directory_index.html**. That template gets two objects in its context:
** directory -- the directory name (a string)**
** file_list -- a list of file names (as strings) in the directory**
Here's the default static/directory_index.html template:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en-us" />
<meta name="robots" content="NONE,NOARCHIVE" />
<title>Index of {{ directory }}</title>
</head>
<body>
<h1>Index of {{ directory }}</h1>
<ul>
{% for f in file_list %}
<li><a href="{{ f }}">{{ f }}</a></li>
{% endfor %}
</ul>
</body>
</html>
Changed in Django 1.0.3: Prior to Django 1.0.3, there was a bug in the view that provided directory listings. The template that was loaded had to be called static/directory_listing (with no .html extension). For backwards compatibility with earlier versions, Django will still load templates with the older (no extension) name, but it will prefer the directory_index.html version.
===== Limiting use to DEBUG=True =====
Because URLconfs are just plain Python modules, you can use Python logic to make the static-media view available only in development mode. This is a handy trick to make sure the static-serving view doesn't slip into a production setting by mistake.
Do this by wrapping an if DEBUG statement around the **django.views.static.serve() **inclusion. Here's a full example URLconf:
from django.conf.urls.defaults import *
from django.conf import settings
urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'news.views.article_detail'),
)
**if settings.DEBUG:**
urlpatterns += patterns('',
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/path/to/media'}),
)
This code is straightforward. It imports the settings and checks the value of the DEBUG setting. If it evaluates to True, then site_media will be associated with the django.views.static.serve view. If not, then the view won't be made available.
Of course, the catch here is that you'll have to remember to set DEBUG=False in your production settings file. But you should be doing that anyway.

View File

@@ -0,0 +1,232 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-21T21:15:54+08:00
====== How to use Django with Apache and mod python ======
Created Friday 21 October 2011
https://docs.djangoproject.com/en/dev/howto/deployment/modpython/
===== Warning =====
Support for mod_python has been deprecated, and will be removed in Django 1.5. If you are configuring a new deployment, you are strongly encouraged to consider using __mod_wsgi __or any of the other supported backends.
The mod_python module for Apache can be used to deploy Django to a production server, although it has been mostly superseded by the simpler mod_wsgi deployment option.
mod_python is similar to (and inspired by) **mod_perl **: It **embeds Python within Apache** and loads Python code into memory when the server starts. Code stays in memory throughout the life of an Apache process, which leads to significant performance gains over other server arrangements.
Django requires Apache 2.x and mod_python 3.x, and you should use Apaches prefork MPM, as opposed to the worker MPM.
===== Basic configuration =====
To configure Django with** mod_python**, first make sure you have Apache installed, with the mod_python module activated.
Then edit your** httpd.conf** file and add the following:
<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root** /mysite # 不应该带有结尾的斜杠**
PythonDebug On
</Location>
...and replace **mysite.settings **with the Python import path to your Django project's settings file.
This tells Apache: "Use mod_python for any URL at or under '/mysite/', using the Django mod_python handler." It passes the value of **DJANGO_SETTINGS_MODULE** so mod_python knows which settings to use.
Because mod_python //does not know we are serving this site from underneath the//__ /mysite/ __//prefix//, this value needs to be passed through to the mod_python handler in Django, via the //PythonOption django.root// ... line. The value set on that line (the last item) should __match the string given in the <Location ...> directive__. The effect of this is that Django will __automatically strip the /mysite string__ from the front of any URLs __before matching them against your URLconf patterns__. If you later move your site to live under /mysite2, you will not have to change anything except the django.root option in the config file.
When using django.root you should make sure that what's left, after the prefix has been removed, __begins with a slash__. Your URLconf patterns that are expecting an initial slash will then work correctly. In the above example, since we want to send things like /mysite/admin/ to /admin/, we need to remove the string /mysite from the beginning, so that is the django.root value. It would be **an error to use /mysite/ **(with a trailing slash) in this case.
Note that we're using the <Location> directive, not the <Directory> directive. The latter is used for pointing at places on your filesystem, whereas **<Location> points at places in the URL structure **of a Web site. <Directory> would be meaningless here.
Also, if your Django project is not on the default__ PYTHONPATH__ for your computer, you'll have to tell mod_python where your project can be found:
<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root /mysite
PythonDebug On
__PythonPath__ "['/path/to/project'] + sys.path" #应该是mysite(也就是project目录)所在的**父目录**
</Location>
The value you use for PythonPath should include the __parent directories __of all the modules you are going to import in your application. It should also include the **parent directory **of the DJANGO_SETTINGS_MODULE location. This is exactly the same situation as setting the Python path for interactive usage. Whenever you try to import something, Python will run through all the directories in sys.path in turn, from first to last, and try to import from each directory until one succeeds.
Make sure that your Python source files' permissions are set such that the Apache user (usually named apache or httpd on most systems) will have **read** access to the files.
An example might make this clearer. Suppose you have some applications under /usr/local/django-apps/ (for example, /usr/local/django-apps/weblog/ and so forth), your settings file is at /var/www/mysite/settings.py and you have specified DJANGO_SETTINGS_MODULE as in the above example. In this case, you would need to write your PythonPath directive as:
**PythonPath "['/usr/local/django-apps/', '/var/www'] + sys.path"**
With this path, import weblog and import mysite.settings will both work. If you had import blogroll in your code somewhere and blogroll lived under the weblog/ directory, you would also need to add /usr/local/django-apps/weblog/ to your PythonPath.
__Remember: the parent directories of anything you import directly must be on the Python path.__
===== Note =====
If you're using Windows, we still recommended that you use **forward slashes **in the pathnames, even though Windows normally uses the backslash character as its native separator. Apache knows how to convert from the forward slash format to the native format, so this approach is portable and easier to read. (It avoids tricky problems with having to double-escape backslashes.)
This is valid even on a Windows system:
PythonPath "['c:/path/to/project'] + sys.path"
You can also add directives such as **PythonAutoReload Off **for performance. See the mod_python documentation for a full list of options.
Note that you should set **PythonDebug Off** on a production server. If you leave PythonDebug On, your users would see ugly (and revealing) Python tracebacks if something goes wrong within mod_python.
**Restart Apache**, and any request to /mysite/ or below will be served by Django.
__Note that Django's URLconfs won't trim (修剪、除去)the "/mysite/" -- they get passed the full URL.__
When deploying Django sites on mod_python, you'll need to__ restart Apache each time you make changes __to your Python code.
===== Multiple Django installations on the same Apache =====
It's entirely possible to run multiple Django installations on the same Apache instance. Just use** VirtualHost** for that, like so:
NameVirtualHost *
<VirtualHost *>
ServerName www.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</VirtualHost>
<VirtualHost *>
ServerName www2.example.com
# ...
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
</VirtualHost>
If you need to put two Django installations within the same VirtualHost (or in different VirtualHost blocks that share the same server name), you'll need to take **a special precaution** to ensure __mod_python's cache doesn't mess things up__. Use the** PythonInterpreter** directive to give different <Location> directives separate interpreters:
<VirtualHost *>
ServerName www.example.com
# ...
<Location "/something">
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
** PythonInterpreter mysite**
</Location>
<Location "/otherthing">
SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
**PythonInterpreter othersite**
</Location>
</VirtualHost>
The values of PythonInterpreter don't really matter, as long as they're **different** between the two Location blocks.
===== Running a development server with mod_python =====
If you use mod_python for your development server, you can avoid the hassle of having to restart the server each time you make code changes. Just set __MaxRequestsPerChild 1__ in your httpd.conf file to **force Apache to reload everything for each request**. But don't do that on a production server, or we'll revoke your Django privileges.
If you're the type of programmer who debugs using scattered print statements, note that __output to stdout__// will not appear in the Apache log and can even cause response errors//.
If you have the need to print debugging information in a mod_python setup, you have a few options. You can __print to stderr __explicitly, like so:
print >> sys.stderr, 'debug text'
sys.stderr.flush()
(note that stderr is buffered, so calling flush is necessary if you wish debugging information to be displayed promptly.)
A more compact approach is to use an assertion:
assert False, 'debug text'
Another alternative is to add **debugging information **to the template of your page.
===== Serving media files =====
Django doesn't serve media files itself; it leaves that job to whichever Web server you choose.
We recommend using a** separate Web server** -- i.e., one that's not also running Django -- for serving media. Here are some good choices:
* lighttpd
* Nginx
* TUX
* A stripped-down version of Apache
* Cherokee
If, however, you have no option but to serve media or static files on the same Apache VirtualHost as Django, here's how you can turn off mod_python for a** particular part** of the site:
<Location "/media">
SetHandler None
</Location>
Just change Location to the **root URL of your media files**. You can also use **<LocationMatch>** to match a regular expression.
This example sets up Django at the site root but explicitly disables Django for the **media** and **static** subdirectories and any URL that ends with .jpg, .gif or .png:
<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</Location>
<Location "/media">
SetHandler None
</Location>
<Location "/static">
SetHandler None
</Location>
<LocationMatch "\.(jpg|gif|png)$">
SetHandler None
</LocationMatch>
===== Serving the admin files =====
Note that the// Django development server// automagically serves the static files of the admin app, but this is not the case when you use any other server arrangement. You're responsible for setting up Apache, or whichever media server you're using, to serve the admin files.
The admin files live in (django/contrib/admin/static/admin) of the Django distribution.
We strongly recommend using** django.contrib.staticfiles** to handle the admin files, but here are two other approaches:
1) Create a symbolic link to the admin static files from within your document root.
2) Or, copy the admin static files so that they live within your Apache document root.
===== Using "eggs" with mod_python =====
If you installed Django from a Python egg or are using eggs in your Django project, some extra configuration is required. Create an extra file in your project (or somewhere else) that contains something like the following:
import os
os.environ['PYTHON_EGG_CACHE'] = '/some/directory'
Here, /some/directory is a directory that the Apache Web server process can** write to**. It will be used as the location for any **unpacking** of code the eggs need to do.
Then you have to tell mod_python to import this file before doing anything else. This is done using the__ PythonImport__ directive to mod_python. You need to ensure that you have specified the **PythonInterpreter** directive to mod_python as described above (you need to do this even if you aren't serving multiple installations in this case). Then add the PythonImport line in the main server configuration (i.e., outside the Location or VirtualHost sections). For example:
PythonInterpreter my_django
PythonImport /path/to/my/project/file.py my_django
Note that you can use an absolute path here (or a normal dotted import path), as described in the mod_python manual. We use an absolute path in the above example because if any Python path modifications are required to access your project, they will not have been done at the time the PythonImport line is processed.
===== Error handling =====
When you use Apache/mod_python, errors will be caught by Django -- in other words, they **won't propagate t**o the Apache level and won't appear in the Apache error_log.
The exception for this is if something is really wonky in your** Django setup**. In that case, you'll see an __"Internal Server Error"__ page in your browser and the full Python traceback in your Apache error_log file. The error_log traceback is spread over multiple lines. (Yes, this is ugly and rather hard to read, but it's how mod_python does things.)
If you get a segmentation fault
If Apache causes a segmentation fault, there are two probable causes, neither of which has to do with Django itself.
* It may be because your Python code is importing the "pyexpat" module, which may conflict with the version embedded in Apache. For full information, see Expat Causing Apache Crash.
* It may be because you're running mod_python and mod_php in the same Apache instance, with MySQL as your database backend. In some cases, this causes a known mod_python issue due to version conflicts in PHP and the Python MySQL backend. There's full information in the mod_python FAQ entry.
If you continue to have problems setting up mod_python, a good thing to do is __get a barebones mod_python site working, without the Django framework. __This is an easy way to isolate mod_python-specific problems. Getting mod_python Working details this procedure.
The next step should be to edit your test code and add an import of any Django-specific code you're using -- your views, your models, your URLconf, your RSS configuration, etc. Put these imports in your test handler function and access your test URL in a browser. If this causes a crash, you've confirmed it's the importing of Django code that causes the problem. Gradually reduce the set of imports until it stops crashing, so as to find the specific module that causes the problem. Drop down further into modules and look into their imports, as necessary.
===== If you get a UnicodeEncodeError =====
If you're taking advantage of the internationalization features of Django (see Internationalization and localization) and you intend to allow users to **upload files**, you must ensure that the environment used to start Apache is configured to __accept non-ASCII file names.__ If your environment is not correctly configured, you will trigger UnicodeEncodeError exceptions when calling functions like os.path() on filenames that contain non-ASCII characters.
To avoid these problems, the environment used to start Apache should contain settings analogous to the following:
export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'
Consult the documentation for your operating system for the appropriate syntax and location to put these configuration items; /etc/apache2/envvars is a common location on Unix platforms. Once you have added these statements to your environment, restart Apache.

View File

@@ -0,0 +1,95 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-22T15:31:56+08:00
====== How to use Django with Apache and mod wsgi ======
Created Saturday 22 October 2011
https://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/#serving-files
Deploying Django with Apache and mod_wsgi is the **recommended way** to get Django into production.
mod_wsgi is an **Apache module** which can be used to host any Python application which supports the Python WSGI interface described in PEP 3333, including Django. Django will work with any version of Apache which supports mod_wsgi.
The official mod_wsgi documentation is fantastic; its your source for all the details about how to use mod_wsgi. Youll probably want to start with the installation and configuration documentation.
===== Basic configuration =====
Once youve got mod_wsgi installed and activated, edit your httpd.conf file and add:
**WSGIScriptAlias / /path/to/mysite/apache/django.wsgi**
The first bit above is the url you want to be serving your application at (/ indicates the root url), and the second is the location of a "WSGI file" -- see below -- on your system, usually inside of your project. **This tells Apache to serve any request below the given URL using the WSGI application defined by that file.**
Next we'll need to actually create this WSGI application, so create the file mentioned in the second part of WSGIScriptAlias and add:
**import os**
**import sys**
**os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'**
**import django.core.handlers.wsgi**
**application = django.core.handlers.wsgi.WSGIHandler()**
If your project is not on your __PYTHONPATH__ by default you can add:
**path = '/path/to/mysite's parent directory'**
**if path not in sys.path:**
** sys.path.append(path)**
just below the import sys line to place your project on the path. Remember to replace 'mysite.settings' with your correct settings file, and '/path/to/mysite' with your own project's location.
===== Serving files =====
**Django **__doesn't serve files itself__**; it leaves that job to whichever Web server you choose.**
We recommend using a separate Web server -- i.e., one that's not also running Django -- for **serving media**. Here are some good choices:
* lighttpd
* Nginx
* TUX
* A stripped-down version of Apache
* Cherokee
If, however, you have no option but to serve media files on the same Apache VirtualHost as Django, you can set up Apache to __serve some URLs as static media, and others using the mod_wsgi interface to Django__.
This example sets up Django at the site root, but explicitly serves robots.txt, favicon.ico, any CSS file, and anything in the /static/ and /media/__ URL space as a static file__. All other URLs will be served using mod_wsgi:
**Alias /robots.txt /usr/local/wsgi/static/robots.txt**
**Alias /favicon.ico /usr/local/wsgi/static/favicon.ico**
**AliasMatch ^/([^/]*\.css) /usr/local/wsgi/static/styles/$1**
**Alias /media/ /usr/local/wsgi/media/**
**Alias /static/ /usr/local/wsgi/static/**
**<Directory /usr/local/wsgi/static>**
**Order deny,allow**
**Allow from all**
**</Directory>**
**<Directory /usr/local/wsgi/media>**
**Order deny,allow**
**Allow from all**
**</Directory>**
**WSGIScriptAlias / /usr/local/wsgi/scripts/django.wsgi**
**<Directory /usr/local/wsgi/scripts>**
**Order allow,deny**
**Allow from all**
**</Directory>**
===== Serving the admin files =====
Note that the Django **development server** automagically serves the static files of the **admin app**, but this is not the case when you use any other server arrangement. You're responsible for setting up Apache, or whichever media server you're using, to serve the admin files.
The admin files live in (**django/contrib/admin/media**) of the Django distribution.
We strongly recommend using __django.contrib.staticfiles__ to handle the admin files, but here are two other approaches:
* Create a symbolic link to the admin static files from within** your document root**.
* Or, copy the admin static files so that they live within your Apache document root.
===== Details =====
For more details, see the mod_wsgi documentation on Django integration, which explains the above in more detail, and walks through all the various options you've got when deploying under mod_wsgi.

View File

@@ -0,0 +1,97 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-27T18:31:44+08:00
====== My Idea Of The Django Blogging App™ ======
Created Thursday 27 October 2011
http://www.muhuk.com/2010/04/my-idea-of-the-django-blogging-app%E2%84%A2/
I am not going to talk about yet another Django-based blogging engine in this post. There are a number of blogging apps which try to be like turn-key solutions, like a WordPress blog. I have skimmed through the code of many such apps, but havent used one yet. Some of them are really high quality apps. What I have in mind is somewhat different though. I would like an app that would allow me to build a blog that satisfies my projects specific requirements.
Let me reiterate the last sentence. Having a Django-based blog just because Django is fashinable is a little dumb in my opinion. If Django-based X blogging engine suits you better than anything else, use it. Why not? But my personal choice of blogging engine is WordPress1. The value of a Django blogging app, for me, is in adding a blog to a Django project. And different projects might have different requirements. So my idea of a Django blogging app is one that is highly configurable and highly extendable.
On the other hand I dont need the convenience of clicking a checkbox on a polished UI. I can write a function. Or I dont necessarily need it to, say, provide a navigation menu. There are apps that do that. Even if there wasnt it shouldnt be the blog apps job. So I am not looking for an instant-blog. I have a Django app in my mind, nothing more.
What Should Be Left Out
Basically any feature that can be provided by another reusable app should be left out. Why should we re-implement something that is already done… and reviewed by others… and tested. Of course this doesnt necessarily mean providing no convenience functions.
No admin. Because we already have one.
No theming. For the love of Flying Spaghetti Monster, you dont need any theming other than what django.template offers. Pre-built themes are for turn-key solutions.
No comments or contact forms. (See django.contrib.comments and django-contact-form)
No official markup format (or formats). This can be handled in the templates without difficulty. But, maybe, pluggable content filters is a good idea. I havent made up my mind on this one entirely. It wont use any markup format by default, that is for sure.
What Should Be Included
Remember, every project has a different set of needed features for its blog. Some need catagories, some need tags and some others need both. But it would end up as a disaster if we implemented each one of those features into a single app. Instead I think it should consist of many small apps that work together. But I wouldnt want to end up having huge spaghetti of apps that all depend on one another, like Pinax does. A minimal amount of core apps2 and then everything else should be optional. By optional I mean you dont have to install packages you wont need.
I think the components (apps) should be activated via adding to INSTALLED_APPS and configured with settings. I cant think of any parameter that needs to be changed dynamically, so why not use the established way of doing configuration in Django.
Two must have features for such a blogging app are previews and scheduled publishing. It is possible that you sometimes write a post quickly and publish it immediately. But I suppose nobody will say they dont care about these two features.
Built-in feeds and sitemaps are also nice to have.
Multiple instances of this blogging app running on the same project? À la admin. I cant make my mind on this one. Sure it would be a nice feature. But it could complicate the code. Peehaps too much for a not so common case.
What do you think about the general idea? Are there any other must-have features? Would you be willing to learn a new app when you are already comfortable with another blogging app?
1: Even though its written in the abomination called PHP. But since there are plugins for everything I dont have to touch the code.
2: One sounds like a good number, if possible.
Bookmark and Share
No related posts.
Tags: blogs, django, python, reusable
This entry was posted on Wednesday, April 28th, 2010 at 12:36 and is filed under Programming. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.
7 Responses to “My Idea Of The Django Blogging App™”
Matthias Kestenholz says:
28.04.2010 at 13:48
Oh yeah, there are other must-have features for something which wants to call itself a blog:
Receiving and sending pings, trackbacks and pingbacks.
Without these, its just another news app with commenting functionality. Thats not what a blog is all about.
Atamert Ölçgen says:
28.04.2010 at 13:56
Good points Matthias, I agree 100%.
Fantomas42 says:
28.04.2010 at 19:28
I totally agree with you when you said : “Why should we re-implement something that is already done… and reviewed by others… and tested. ” And I understand very well why you have choose WordPress, it is really powerfull, but a little bit to ugly for me to maintain.
My conception of a weblog application is really close of your. So that why you should check the release of my weblog application, and give me some feed back.
http://github.com/Fantomas42/django-blog-zinnia
@Matthias Kestenholz Pingback and trackbacks are a part of a blogging system, but not the essential. And some pluggable applications does it very well, for example :
http://github.com/svetlyak40wt/django-pingback
Sorry for my french !
Atamert Ölçgen says:
28.04.2010 at 22:12
@Fantomas42, Your app looks good. But its all-or-nothing this way. I would like to be able to choose a subset of available features. Ill take a closer look later, though.
Josh says:
28.04.2010 at 22:39
I agree with your ideas for the most part. Im of the persuasion that a lot of external dependencies make things more complicated than they need to be. A few here and there are fine, I say.
Im curious what your opinion of django-articles is (its my pet project). Im all for making it more configurable. If you make suggestions, Ill probably take them to heart and try to apply them to the codebase! Im not suggesting that django-articles is the end-all be-all blog engine for Django, but it might well be close enough to what youre after… :)
origiNell says:
29.04.2010 at 13:25
“There are a number of blogging apps which try to be like turn-key solutions, like a WordPress blog.”
Thats what bothered me too.. I wrote my own blogging engine which tries to be as modular as possible.. or at least I try to make everything optional via settings.. ;-) The only thing thats really hardcoded is a simple comment spam protection (which I might remove in favor of disqus) and markdown as markup of choice..
http://github.com/originell/simpleblog/tree
Julien Phalip says:
03.05.2010 at 13:06
I couldnt agree more! In that same spirit weve built a blog framework to make it super easy to create your own blog app and extend it to your needs: http://github.com/glamkit/glamkit-blogtools Take a look at it and see what you think ;)

View File

@@ -0,0 +1,65 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-22T16:15:23+08:00
====== Serving Django Admin Static Media Files with Apache WSGI on Ubuntu ======
Created Saturday 22 October 2011
http://blog.videntity.com/?p=507
Here is a quick and simple configuration code recipe to serve the admin static files in a production environment using modWSGI and Apache 2.
Modify your apache2 configuration file. By default that would be:
/etc/apache2/sites-available/default
Just add the line:
**Alias /media/ /var/www/media/**
..under your VirtualHost setting, like so:
**<VirtualHost *:80>**
** ServerAdmin webmaster@localhost**
** Alias /media/ /var/www/media/**
** DocumentRoot /var/www**
** <Directory />**
** Options FollowSymLinks**
** AllowOverride None**
** </Directory>**
** <Directory /var/www/>**
** Options Indexes FollowSymLinks MultiViews**
** AllowOverride None**
** Order allow,deny**
** allow from all**
** </Directory>**
**WSGIScriptAlias / /home/ubuntu/RESTCat/apache/django.wsgi**
**.**
**.**
**</VirtualHost>**
Note that the WSGIScriptAlias points to your **Django application configuration file**. I keep it along side my project in a folder called apache in a file called django.wsgi.
Now add a symbolic link to point apache to the admin static content like so:
**sudo ln -s /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media /var/www/media**
Now simply restart apache.
**sudo apache2ctl restart**
Your admin static files should now be served!

View File

@@ -0,0 +1,48 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-21T22:28:40+08:00
====== django+apache配置文件详解 ======
Created Friday 21 October 2011
setting.py是django项目的重要配置文件现将几个重要参数解释一下
#这个是上传文件的“本地”绝对路径。。。
MEDIA_ROOT = '/home/lion/www/uploads/'
#这个是上传文件的url相对路径django将通过这个相对路径来生成上传文件的真实的url路径否则django对上传的文件无法正确定位
MEDIA_URL = '/uploads/'
#这个也是url相对路径是和Admin Sitedjango内置的后台管理页面相关的资源文件这个路径设置不正确将导致Admin Site的页面显示不正常
ADMIN_MEDIA_PREFIX = '/media/'
apache并没有内置对python语言的支持所以需要安装mod_python插件
在debian下安装只要以root权限输入以下命令
apt-get install libapache2-python2.x2.x是版本比如说2.5
httpd.conf是apache的主要配置文件
以下是我的httpd.conf
#这里设置了在根目录下使用mod_pyhton解释器+django
<Location "/">使用解释器的url路径
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE www.settings
#上面的这句重点解释一下我们用dejango生成的web程序正常是在同一个目录下这个目录对python来说是一个“模块”切记
#因此如果我们的web程序目录名是www,目录下的配置文件是settings.py 那么settings这个"模块"在python中的表示就是 www.settings
#于是就有了以上的 www.settings 这个模块了
PythonOption django.root /home/lion/#这里要设置成你的web程序“所在”的目录也就是web目录的父目录
PythonDebug On
PythonPath "['/home/lion/'] + sys.path"# 一般情况下你的web程序模块不再python的默认搜索目录里面所以还是把这个web程序“所在”的目录加入python的搜索目录当中才可以。
</Location>
Alias /media/ /usr/share/python-support/python-django/django/contrib/admin/media/# 定义Admin Site相关资源文件目录为/media/
Alias /uploads/ /home/lion/www/uploads/# 定义上传目录为/uploads/注意要想能够正常上传文件需要开启apache运行用户对它的写入权限。apache一般以www-data 或者 nobody 用户运行。
<Location "/media/">#设定/media/目录不使用任何解释器包括python
SetHandler None
</Location>
<Location "/uploads/">#设定/uploads/目录不使用任何解释器。--否则无法访问上传后的文件,不信你试试看~~
SetHandler None
</Location>

View File

@@ -0,0 +1,28 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T17:57:50+08:00
====== django1.3的staticfiles ======
Created Sunday 23 October 2011
http://haoluobo.com/2011/07/django1-3%E7%9A%84staticfiles/
django1.3新加入了一个静态资源管理的appdjango.contrib.staticfiles。在以往的django版本中静态资源的管理一向都是个问题。
部分app发布的时候会带上静态资源文件在部署的时候你必须手动从各个app中将这些静态资源文件复制到同一个static目录。
在引入staticfiles后你只需要执行./manage.py collectstatic就可以很方便的将所用到app中的静态资源复制到同一目录。
staticfiles的引入方便了django静态文件的管理不过感觉staticfiles的文档写的并不是太清楚初次使用的时候还是让我有些困惑。
下面简单的介绍一下staticfiles的主要配置
* STATIC_ROOT运行manage.py collectstatic后静态文件将复制到的目录。注意不要把你项目的静态文件放到这个目录。这个目录只有在运行collectstatic时才会用到。我最开始想当然的以为这个目录和MEDIA_ROOT的作用是相同的致使在开发环境下一直无法找到静态文件。
* STATIC_URL设置的static file的起始url这个只可以在template里面引用到。这个参数和MEDIA_URL的含义差不多。
* STATICFILES_DIRS除了各个app的static目录以外还需要管理的静态文件位置比如项目公共的静态文件差不多。和TEMPLATE_DIRS的含义差不多。
* 各个APP下static/目录下的静态文件django的开发服务器会自动找到这点和以前APP下的templates目录差不多。
* 在urls.py中加入静态文件处理的代码
* from django.contrib.staticfiles.urls import staticfiles_urlpatterns
* # ... the rest of your URLconf goes here ...
* urlpatterns += staticfiles_urlpatterns()

View File

@@ -0,0 +1,37 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-22T22:18:40+08:00
====== django media 设置 ======
Created Saturday 22 October 2011
http://hi.baidu.com/uniqcmt/blog/item/e64a0c1e2d9dd41b40341770.html
在一个 model 中使用 FileField 或 ImageField 需要以下步骤:
1) 在你的 settings 文件中, 定义一个完整路径给 __MEDIA_ROOT__ 以便让 Django在此处保存**上传文件**. (出于性能考虑,这些文件并不保存到数据库.) 定义 __MEDIA_URL__ 作为**该目录的公共 URL.** 要确保该目录对 WEB 服务器用户帐号是可写的.
2) 在你的 model 中添加 FileField 或 ImageField, 并确保定义了 __upload_to__ 选项,以告诉 Django 使用 MEDIA_ROOT 的哪个**子目录**保存上传文件.
3) 你的数据库中要保存的只是文件的路径(相对于 MEDIA_ROOT). 出于习惯你一定很想使用 Django 提供的 get_<fieldname>_url 函数.举例来说,如果你的 ImageField 叫作 mug_shot, 你就可以在模板中以 {{ object.get_mug_shot_url }} 这样的方式得到图像的绝对路径.
===== settings.py 设置 =====
# 媒体文件的绝对路径
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = 'D:/django/hwedding/images/'
# 媒体文件的相对路径
# URL that handles the media served from MEDIA_ROOT.
# Example: "http://media.lawrence.com"
MEDIA_URL = '/smedia/'
# admin管理素材路径
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/'
# urls.py 影射路径: 将 url smedia 影射到 settings.MEDIA_ROOT
(r'^smedia/(?P<path>.*)$', 'django.views.static.__serve__',{'document_root': settings.MEDIA_ROOT}),
# models.py 上传图片字段设置
image = models.ImageField('介绍图片',upload_to='./up')
相当于传到 D:/django/hwedding/images/up 目录下浏览时通过__/smedia/up/__访问

View File

@@ -0,0 +1,156 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-22T22:41:18+08:00
====== linux下nginx+python+fastcgi部署总结(django版) ======
Created Saturday 22 October 2011
http://www.vimer.cn/2011/07/linux%E4%B8%8Bnginxpythonfastcgi%E9%83%A8%E7%BD%B2%E6%80%BB%E7%BB%93django%E7%89%88.html/comment-page-1
最近因为项目上的需要开始大量使用nginx因此也想趁机将以前常用的django+apache的架构换成**django+nginx+fastcgi**,此文是整个搭建的步骤,主要留作备忘,也希望对大家有所帮助。
注意虽然本文成功的搭建了django运行fastcgi的实例但是在实际运行中发现了很多问题比如程序执行异常进程在每次请求之后退出之类的。可能是我机器的问题也可能是程序本身bug大家如果用来搭建外网环境请务必多多测试。
===== 一. 编译nginx =====
在网上买了一本《实战nginx-取代Apache的高性能服务器》写的比较浅主要是些配置方面的东西不过却正是目前我所需要的。由于需要支持__https和rewrite__所以除了nginx的源码之外又下载了 openssl-0.9.8r.tar.gz 和 pcre-8.12.tar.gz把他们和nginx-1.0.4.tar.gz放到同一个目录。
为了方便编译,笔者写了一个脚本,代码如下:
#=============================================================================
#脚本所在绝对目录
abs_path(){
local path=$1
local basename=$( basename $path )
local dirname=$( dirname $path )
cd $dirname
if [ -h $basename ]; then
path=$( readlink $basename )
abs_path $path
else
pwd
fi
}
#=============================================================================
#依赖的目录
src_base_dir=$( abs_path $0 )
src_openssl_dir=$src_base_dir'/openssl-0.9.8r'
src_pcre_dir=$src_base_dir'/pcre-8.12'
src_nginx_dir=$src_base_dir'/nginx-1.0.4'
#=============================================================================
#目标的目录
dest_base_dir=$src_base_dir'/release'
dest_nginx_dir=$dest_base_dir'/nginx'
#=============================================================================
#把所有的tar.gz解压
find . -name "*.tar.gz" | xargs -IX tar zxvf X
#=============================================================================
#编译nginx
cd $src_nginx_dir
chmod u+x ./configure
./configure --with-http_stub_status_module --with-http_ssl_module --with-openssl=$src_openssl_dir --with-pcre=$src_pcre_dir --prefix=$dest_nginx_dir
make && make install
编译完成后我们就需要来配置nginx了
===== 二.配置nginx =====
在server配置项下增加
location / {
#fastcgi_pass 127.0.0.1:9001;
fastcgi_pass unix:django.sock;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
}
location** /admin_media/** {
alias /usr/local/lib/python2.7/site-packages/django/contrib/admin/media/;
break;
}
location **/site_media/** {
alias /home/dantezhu/htdocs/ngx_django/media/;
break;
}
这里的3个location配置分别解决了与python进程通信、django后台管理端样式存放、网站样式存放的问题。对照着apache的配置来看就很容易明白了
WSGIPythonEggs /tmp
<VirtualHost *>
ServerName fuload.qq.com
** WSGIScriptAlias / /home/dantezhu/htdocs/fuload/conf/setting.wsgi**
<Directory />
Options FollowSymLinks
AllowOverride
Order allow,deny
Allow from all
</Directory>
<Directory "/home/dantezhu/htdocs/fuload/mysite">
Order Deny,Allow
Deny from all
</Directory>
**Alias /admin_media "/usr/local/lib/python2.7/site-packages/django/contrib/admin/media"**
<Directory "/usr/local/lib/python2.7/site-packages/django/contrib/admin/media">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
#AliasMatch /site_media/(.*\.(css|gif|png|jpg|jpeg)) /home/dantezhu/htdocs/fuload/media/$1
** Alias /site_media /home/dantezhu/htdocs/fuload/media/**
<Directory "/home/dantezhu/htdocs/fuload/media/">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
</VirtualHost>
===== 三.安装fastcgi依赖 =====
需要到 http://trac.saddi.com/flup%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85%EF%BC%8C%E4%B9%8B%E5%90%8Efastcgi%E6%89%8D%E8%83%BD%E5%A4%9F%E6%AD%A3%E5%B8%B8%E5%90%AF%E5%8A%A8。
===== 四.启动django =====
创建django project的过程我们就不说了只列出启动/停止的命令:
启动:
#python manage.py runfcgi daemonize=true pidfile=`pwd`/django.pid host=127.0.0.1 port=9001 maxrequests=1 &
python manage.py __runfcgi__ daemonize=true pidfile=`pwd`/django.pid socket=/home/dantezhu/nginx/sbin/django.sock maxrequests=1 &
停止:
kill -9 `cat django.pid`
===== 五.启动nginx =====
启动:
./nginx -p /home/dantezhu/nginx/
停止:
kill -QUIT `cat ../logs/nginx.pid`
重新载入配置:
./nginx -t -c `pwd`/../conf/nginx.conf
kill -HUP `cat ../logs/nginx.pid`
成功显示了django的后台界面:
OK到此为止大功告成

View File

@@ -0,0 +1,110 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T20:48:21+08:00
====== 在Django中使用CKEditor ======
Created Sunday 23 October 2011
http://2goo.info/blog/panjj/Django/2010/11/15/139
在博客中使用富文本编辑器是很常见的今天尝试在Django中使用比较知名的CKEditor。前提条件是通过静态文件的正确配置可以参考之前写的《Django静态文件的配置》今天不再累赘。
一 前提条件:
1. 找到第三方支持插件django-ckeditor
相关开源项目地址https://github.com/dwaiter/django-ckeditor
2. python中安装simplejson
相关包地址http://pypi.python.org/pypi/simplejson/
安装方法和安装其他Python第三方库是一样的下载该包解压到包的目录下执行 python setup.py install过程中python会自动寻找依赖的类库所以你必须能连上网络
二 配置CKEditor环境
你可以选择把django-ckeditor安装到python里也可以把下载的django-ckeditor作为自己的app来用。我选择后者。
下载的django-ckeditor目录结构
ckeditor
setup.py
...
把django-ckeditor里的ckeditor直接粘贴到我们的项目中然后把该app的templates和media挪出来整个项目的目录结构
app_test #这是我特意创建的一个自己的app作为测试用。
ckeditor
static
--|ckeditor
----|...
--|css
----|...
templates
--|ckeditor
__init__.py
manage.py
settings.py
url.py
整个过程就是把下载的ckeditor文件夹当成一个全新的app熟悉的Django的就不必一一介绍了如果你和我一样是新手不用担心我们教程后面有一个基本的实例 供参考。
我们在settings.py最后一行给ckeditor写一些配置
CKEDITOR_CONFIGS = {
'default': {
'toolbar':[
['Source','-','Save','NewPage','Preview','-','Templates'],
['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print','SpellChecker','Scayt'],
['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
['Form','Checkbox','Radio','TextField','Textarea','Select','Button', 'ImageButton','HiddenField'],
['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
['Link','Unlink','Anchor'],
['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
['Styles','Format','Font','FontSize'],
['TextColor','BGColor'],
['Maximize','ShowBlocks','-','About']
],
'width': 650,
'height': 200,
'toolbarCanCollapse': False,
},
'simple_toolbar': {
'toolbar': [
[ 'Bold', 'Italic', 'Underline' ],
],
'width': 650,
'height': 50,
},
}
一个是默认的配置几乎是ckeditor的全部功能一个是简单的配置仅仅提供几个再简单不过的功能。更具体的配置参考CKEditor官方网站吧。
三 使用CKEidor
涉及到表单控件的我们习惯使用Django的forms。
我们在app_test里定义了一个forms类
#coding=utf-8
from django import forms
from ckedj.ckeditor.widgets import CKEditor #ckedj是定义的项目名
class BlogPostForm(forms.Form):
title = forms.CharField()
# This field will render as a CKEditor with the 'simple_toolbar' config.
subtitle = forms.CharField(widget=CKEditor(ckeditor_config='simple_toolbar'))
# This field will render as a CKEditor with the 'default' config.
body = forms.CharField(widget=CKEditor())
代码里subtitle使用简易的配置而body使用了默认的。
在html文件中注意要引用CKEditor的初始化脚本前提是保证静态文件能成功解析哦django-ckeditor说明文档中没有这个说明所以过程中折腾了半天别说我不提醒你...,初始化脚本ckeditor.js在ckeditor/ckeditor下。废话少说看代码
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script type="text/javascript" src="/site_media/ckeditor/ckeditor/ckeditor.js"></script>
</head>
<body>
<form>
<table border="0" cellspacing="0">
{{form.as_table}}
</table>
</form>
</body>
</html>
这样就能在Django中正常使用CKEditor了。如图

View File

@@ -0,0 +1,46 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-21T22:28:04+08:00
====== 在Django中计算出你的项目中的template dir和media dir ======
Created Friday 21 October 2011
在django中需要设定一些目录的路径 比如TEMPLATE_DIRSSTATIC_DOC_ROOTLOCALE_PATHS 等等, 如果是多人一起开发一个项目,每个人的路径可能都不一样。 最理想的方式是都把资源文件放在目录中我们可以通过相对路径来得到那些资源的path。 下面说下我的做法django的配置文件是settings.py。 这个文件本省就是一个py文件。 所以我们如果可以计算出settings.py的路径那我们就自然知道放在项目中的资源的路径了。
在settings.py的开头加入以下代码。
Java代码 收藏代码
import os
base_dir = os.path.dirname(__file__)
这样我们就得到了settings.py的文件在的文件夹的path。 所以我们就可以把TEMPLATE_DIRS定义成
Java代码 收藏代码
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
base_dir + "/website/templates",
)
STATIC_DOC_ROOT = base_dir + '/website/zoomino_media'
LOCALE_PATHS = (base_dir + "/conf/locale",)
项目结构为
+project
+conf
+locale
+website
+templates
+zoomino_media
settings.py

View File

@@ -0,0 +1,68 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-23T22:43:05+08:00
====== 在Django模板中使用css、javascript 等静态文件 ======
Created Sunday 23 October 2011
http://a280606790.iteye.com/blog/1107454
在使用Django开发的Web项目中是避免不了使用css、javascript、js等静态文件的而对于这些静态文件的处理django官网这样写Django itself doesnt serve static (media) files, such as images, style sheets, or video. It leaves that job to whichever Web server you choose.就是说django本身不处理类似于图片、样式表、视频等静态文件它将此项工作交给了你选择的Web服务器。
在网上搜索到的django项目处理静态文件的示例中大家似乎都在使用如下的方法让django处理静态文件
urlpatterns += patterns('',
(r'^static/(?P.*)$', 'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT}),
)
而对于django.views.static.serve方法django官网说得很清楚Using this method is inefficient and insecure . Do not use this in a production setting. Use this only for development.就是说这种方法是低效且不安全的,不要在生产环境使用此方法,只在开发环境使用。
这时对于静态文件的处理我们只能使用我们选择的Web服务器来处理了。比如使用nginx服务器的话可以如下设置
先设置settings.py,如下,
MEDIA_ROOT = '/home/denghaiping/workspace/djcode/mysite/static/'
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = '/static/'
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = ''
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
# URL prefix for admin static files -- CSS, JavaScript and images.
# Make sure to use a trailing slash.
# Examples: "http://foo.com/static/admin/", "/static/admin/".
ADMIN_MEDIA_PREFIX = '/static/admin/'
apache2 配置如下:
<Location "/static/">
SetHandler None
Order allow,deny
Allow from all
</Location>
Alias /static /home/denghaiping/workspace/djcode/mysite/static
Alias /static/admin /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media
<Location "/static/admin">
SetHandler None
Order allow,deny
Allow from all
</Location>
如此配置以后就可以让web服务器来高效的处理静态文件而让django来处理动态内容。

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,76 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-22T20:23:51+08:00
====== 在 浪点 上部署 Django ======
Created Saturday 22 October 2011
http://hi.baidu.com/uniqcmt/blog/item/c32e641bbf0995f2af51338d.html
今天早上问浪点的客服拿来了SSH的帐号正式开始在上面部署Django了。
玩转SSH
浪点虚拟主机的SSH另指定了2222作端口
ssh username@hostname -p 2222
突然发现终端有问题怎么跟平常的不一样原来是SH而非Bash于是输入bash切换到Bash但是如何让终端默认就是Bash呢 即在登录时就指定命令,把.profile的内容给清空了。Shell还能这样玩今天学到了很多。
实在没办法了就暂时把默认Shell这个问题搁置一下了到时找客服。
测试Django
我在服务器上运行Pythonimport django查看了一下django.VERSION发现服务器是0.96.0版的不会吧至少得应该是0.96.2啊那个版本还有Bug和安全漏洞呢看来下次联系客服同志时要跟他们说一声。
先测试一下Django吧
来到public_html目录然后django-admin.py startproject onlytest建立一个Django工程然后再建立.htaccess文件
.htaccess
AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ django.fcgi/$1 [QSA,L]
再在同目录建立django.fcgi文件
#!/usr/bin/python
#-*-coding:UTF-8-*-#
import sys, os
projectName = onlytest #项目名称 “py”
pathAdd = os.path.dirname(os.path.abspath(__file__)) #项目所在目 /var/www/
projectPath = pathAdd + /%s/ % (projectName) #项目路径 /var/www/py/
sys.path.insert(0, pathAdd);
os.chdir(projectPath)
os.environ["DJANGO_SETTINGS_MODULE"] = %s.settings % (projectName)
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method=”threaded”, daemonize=”false”)
然后访问主页,一切正常。
好了下一步使用新的Django。
使用SVN版的Django
服务器上没有svn命令所以只好自己打个包用scp传了上去以下命令格式
scp -P 2222 django-0.97.zip usename@hostname:/path/anotherpath/
传好以后把django解压到~/python下然后编辑.profile文件加入下面两行如果默认是bash加到.bashrc也可以
export PATH=$PATH:$HOME/python/django
export __PYTHONPATH__=$PYTHONPATH:$HOME/python
然后source ~/.profile这样运行Python的导入django的就是SVN版了导出PATH是为了运行最新版的django-admin.py。
但是已经运行的fastcgi和Python实例似乎没接受这个新变量当时没找到重启的方法好在还有另外的办法在django.fcgi这个文件的form django前再插入一句
sys.path.insert(0, “PATH_TO_HOME/python”)
**因为修改了django.fcgi所以系统会自动重新运行这个实例**因为新的PYTHONPATH已经导入所以import django时就是最新版本的了。
=======
开始的时候 用mysql 怎么也连接不上去django里面也提示有错误自己尝试了很久
不行了打电话问结果原因是浪点的mysqld不支持用“localhost”来连接只能用IP也就是127.0.0.1来连接。
呵呵,以后不懂还是要多问。

View File

@@ -0,0 +1,11 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-24T19:53:21+08:00
====== 有用的第三方APP ======
Created Monday 24 October 2011
1.django-grappelli--------admin美化插件
http://readthedocs.org/docs/django-grappelli/en/latest/quickstart.html
git://github.com/sehmaschine/django-grappelli.git
2.

View File

@@ -0,0 +1,7 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-24T14:45:12+08:00
====== 静态文件管理 ======
Created Monday 24 October 2011

View File

@@ -0,0 +1,156 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-24T11:02:36+08:00
====== 1 django 处理静态文件 ======
Created Monday 24 October 2011
用Django框架时静态文件如CSS/JS/IMG的处理分为两种方式
1.使用Django处理。
2. 使用Web服务器如Apace/Ngix等处理。
第一种方式不推荐在生产环境中使用因为它的性能很差。Django本身应该只用于处理动态页面请求。
下面分别介绍两种方式的配置方式:
===== 1.使用Django处理静态文件请求 =====
不管如何配置Django处理静态文件请求时会搜索INSTALLED_APPS中各APP的static目录以及
STATICFILES_DIRS中列出的目录因此只要静态文件包含在这些路径中Django就可以找到它们。
STATIC_ROOT只用于生产环境STATICFILES_DIRS用于测试环境
使用Django处理静态文件请求时需要配置三个文件settings.py、urls.py以及模板文件中对这些
静态文件的引用方式。
==== settings.py配置选项 ====
import os.path,logging, sys
from os.path import join
#通过运行时确定静态文件的路径而不是将路径硬编码,这可以提高灵活性。
settings_path = os.path.abspath(os.path.dirname(__file__))
#MEDIA_ROOT用于指定__用户上传__的静态文件所放的绝对路径
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
#指定为本配置文件所在目录的media/目录下放置用户上传的静态文件。
**MEDIA_ROOT** = join(settings_path, 'media/')
MEDIA_URL有两种用途
1. 可以用作模板文件中CSS/JS/IMG等与用户有关的静态文件如头像等的路径前缀。
2. 定义请求URL中的静态文件命名空间(MEDIA_URL后的所有内容为静态文件在
MEDIA_ROOT中的文件路径)。
MEIDA_URL可以有两种定义方式
1. 若本地的模板文件使用远程文件服务器(没有使用Django)上的静态文件,则其定义形式为
MEDIA_URL = "http://example.com/media/"
2.若模板文件使用本地MEDIA_ROOT中的文件(一般是用户上传的静态文件),则其定义形式为
MEDIA_URL = "/media/"
注意Django在生成动态页面时会用该设置值替换模板文件中MEIDA_URL变量所以客户端浏览器
在收到返回的动态页面文件后可能向example.com文件服务器或Django框架请求CSS/JS/IMG等静态
文件。但是Django默认是不提供静态文件服务的所以需要配置(如下文所示)。第一种形式一般用于生产环境,
第二种形式一般用于开发、测试如果文件服务器和Django位于同一台主机则对静态文件的引用需要使用
第二种方式,详见下文)。
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
#指定以/media/为前缀的URL地址空间访问本地MEDIA_ROOT中的静态文件
**MEDIA_URL** = '/media/'
#示例:
如果用户浏览器向本机发送: http://127.0.0.1/media/css/style.css%E8%AF%B7%E6%B1%82
则Django会将/media/去掉后的css/style.css作为MEDIA_ROOT中的文件名然后
将读取的内容返给客户端。
#将MEDIA_URL指定为远程文件服务器中静态文件所在的目录
#客户端浏览器在收到动态页面后会向该URL指定的主机请求静态文件。
** MEDIA_URL** = "http://example.com/media/"
**STATIC_ROOT**中存放的是Django从**INSTALLED_APPS和STATICFILES_DIRS **中收集到的
静态文件(然后将它们删除),这样便于在生产环境中部署项目(只需把STATIC_ROOT拷贝到文件服
务器上然后将STATIC_URL指向该服务器和该目录即可, 当然文件服务器可能与Django框架运行在
同一台主机上)。
注意STATIC_ROOT__ 只用于生产环境__中且不能与STATICFILES_DIRS指向同一个目录因为colletcstatic
命令会将后者的内容放到前者位置。用户不应该在STATIC_ROOT中放置自己的文件自己的文件应该放在
STATICFILES_DIRS中。当开发结束后运行collectstatic命令将**INSTALLED_APPS和**
** STATICFILES_DIRS **中的文件统一收集到本地**STATIC_ROOT**中并将其拷贝到Web服务器能找
到的目录中(同时要配置STATIC_URL指向Web服务器的静态文件目录)。
各APP的静态文件一般存放在APP根目录下的static/app-name目录中这样运行
python manage.py collectstatic命令时Django会将app-name目录放到STATIC_ROOT下
(注意此时对APP的静态文件引用的方式是STATIC_URL/app-name/)。
当在开发、测试的过程中为了方便一般使用Django处理静态请求但要注意__一定不要运行__
collectstatic命令因为STATIC_ROOT位于project的根目录中project 目录一般不会被加入
到INSTALLED_APPS中因此其下的STATIC_ROOT不会被Django搜索到(同时由于APP中的staitc目录
都被转移到STATIC_ROOT目录中因此Django会出现搜索不到任何静态文件的现象)。
这时有两种解决办法:
1.把project目录加入到INSTALLED_APPS中。
2.把STATIC_ROOT加入到STATICFILES_DIRS
但是这两种方法都不太好,因此用Django处理静态文件请求的__最好方法__是将静态文件放在INSTALLED_APPS的static或
STATICFILES_DIRS的目录列表中。
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in s' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
**STATIC_ROOT** = join(settings_path, 'static/')
#STATIC_URL的定义方式和用途与MEDIA_URL类似只不过前者定义的命名空间与用户上传
的文件无关。STATIC_URL一般用于定义模板中CSS/IMG/JS对象的位置。当Django收到用户浏览器
对STATIC_URL定义的命名空间中的文件请求时Django会查找INSTALLED_APPS和STATICFILES_DIRS
中的目录文件。如果将STATIC_URL指定为远程主机则Django在生成动态页面时会将其中的静态文件访问
地址设置为STATIC_URL,这时客户端浏览器会向STATIC_URL中指定的主机请求静态文件。
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
**STATIC_URL** = '/static/'
#STATICFILES_DIRS用于定义**用户额外**(非INSTALLED_APPS中各APP/static)的静态文件存放位置。
# Additional locations of static files
**STATICFILES_DIRS** = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
"./static/",
)
#下面两个变量用于定义admin页面的静态文件地址和URL命名空间前缀。
#注意Django对admin media的处理是__单独进行__的(这可以从urls.py中对admin命名空间的匹配看出来。)
#Django默认(不改变ADMIN_MEDIA_PREFIX值)使用__系统自带__的admin media但是一旦改变ADMIN_MEDIA_PREFIX
的值Django将使用该变量的值来查找admin media.
#ADMIN_MEDIA_PREFIX默认值为 '/static/admin/'使用该值时ADMIN_MEDIA_ROOT可以设为__任意值__
甚至不设置也行。但是一旦将该值更改则对应的目录中必须要有admin的各CSS/JS/IMG文件。
# URL prefix for admin static files -- CSS, JavaScript and images.
# Make sure to use a trailing slash.
# Examples: "http://foo.com/static/admin/", "/static/admin/".
**ADMIN_MEDIA_PREFIX** = '/static/' + "grappelli/"
#ADMIN_MEDIA_ROOT变量暂时没有发现其用途。
ADMIN_MEDIA_ROOT = join(settings_path, 'static/admin/')
#如果使用Django处理静态文件一定要把staticfiles添加到INSTALLED_APPS列表中。
**INSTALLED_APPS** = (
"django.contrib.staticfiles",
)
===== urls.py设置 =====
#用于处理admin系统
(r'^admin/', include(admin.site.urls)),
#注意这里的static前缀一定要与STATIC_URL项匹配,但是document_root可以任意设置
甚至为空字符串(因为staticfiles将负责查找这些静态文件)。这里的URL用来匹配客户端
浏览器发来的静态文件请求。
(r'^**static**/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.STATIC_ROOT}),
#用来匹配用户上传文件的URL也就是查找用户浏览器请求以前上传的静态文件。
#注意这里的documetn_root__一定要设为__MEDIA_ROOT即用户上传的文件保存地址。
(r'^media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.**MEDIA_ROOT**}),
==== 模板中对这些静态文件的引用 ====

View File

@@ -0,0 +1,57 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-24T20:17:26+08:00
====== Django - Static file not found ======
Created Monday 24 October 2011
http://stackoverflow.com/questions/6014663/django-static-file-not-found
I've seen several posts for this issue but didn't found my solution.
I'm trying to serve static files within my Django 1.3 **development environment**.
Here are my **settings.py**
...
STATIC_ROOT = '/home/glide/Documents/django/cbox/static/'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
'/static/',
)
...
My** urls.py**
urlpatterns = patterns('',
...
url(r'^static/(?P<path>.*)$', 'django.views.static.serve',
{'document_root', settings.STATIC_ROOT}
),
...
);
My /home/glide/Documents/django/cbox/static/ directory is like
css
main.css
javascript
image
I get a 404 error when trying to access http://127.0.0.1:8000/static/css/main.css.
Do I have to specify patterns for css, javascript and images individually ?
-------------------------------------------------------------------------------------------------------
In fact I** confounded** STATIC_ROOT and STATICFILES_DIRS
Actually I was not really understanding the utility of STATIC_ROOT. I thought that it was the directory on which I have to put my common files. This directory is used __for the production__, this is the directory on which static files will be put (collected) by **collectstatic**.
__STATICFILES_DIRS__ is the one that I need.
Since I'm in a development environment, the solution for me is to **not use STATIC_ROOT **(or to specify another path) and set my common files **directory in STATICFILES_DIRS**:
#STATIC_ROOT = (os.path.join(SITE_ROOT, 'static_files/'))
import os
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
STATICFILES_DIRS = (
os.path.join(SITE_ROOT, 'static/'),
)

View File

@@ -0,0 +1,47 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-24T20:04:49+08:00
====== Django static media ======
Created Monday 24 October 2011
I spent too long tonight figuring out a weird problem.
On a dev server, I was using **django.views.static.serve** to serve media files. But it was returning 404 (not found) for any file.
The requests for media files werent even showing up in Djangos **built-in servers** output. That had me baffled until I dug deep enough in Djangos code to figure it out.
The **ADMIN_MEDIA_PREFIX** was the same as **MEDIA_URL.** That was it.
Djangos built-in server doesnt log requests for **admin media**, so thats why there was no log output.
The built-in server also **handles admin media separately**, so when I tried to request a media file, it intercepted and looked for it in the admin media.
-------------------------------------------------------
The term “media” always struck me as a poor choice, as it means both everything and nothing and is guaranteed to confuse a Django newcomer (as it once did confuse me). Which is why my Django deployments are set up with what I consider less confusing terminology:
/upload the stuff that users uploaded to the server, i.e. what Django refers to as media (served under MEDIA_URL and stored in MEDIA_ROOT on the filesystem).
Django将用户上传的文件称为media
/static the static part of my project/site, such as icons, Javascript files, CSS, etc. (I keep this well separate from /upload, as it is truly static and lives in version control, unlike /upload)
被项目或APP中不变的文件称为static
/adminmedia the static parts of Djangos admin interface, which is served under ADMIN_MEDIA_PREFIX and part of Django. Arguably this should live under __/static/admin__, but I prefer the clean separation in case I need to more one or the other to a separate host for whatever reason (performance, CDN, …)
Django admin 界面的静态文件称为ADMIN_MEDIA它的位置在 ADMIN_MEDIA_PREFIX 变量中指定,默认值为/static/admin, 一旦改变该值
则相应目录中一定要有admin media文件。
> MEDIA_ROOT
the directory where you upload media
> MEDIA_URL
the url where your site media - css, js, icons etc live
> ADMIN_MEDIA_PREFIX
the alias to where the admin media lives - django/contrib/admin/media

View File

@@ -0,0 +1,278 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-21T22:31:17+08:00
====== Managing static files ======
Created Friday 21 October 2011
Django developers mostly concern themselves with the **dynamic parts** of web applications the **views and templates** that render anew for each request. But web applications have other parts: the static files (images, CSS, Javascript, etc.) that are needed to render a complete web page.
For small projects, this isnt a big deal, because you can just keep the static files somewhere your** web server** can find it. However, in bigger projects especially those comprised of multiple apps dealing with the multiple sets of static files provided by each application starts to get tricky.
Thats what __django.contrib.staticfiles__ is for: it collects static files from each of your applications (and any other places you specify) into a single location that can easily be served in production.
=== Note ===
If youve used the django-staticfiles third-party app before, then django.contrib.staticfiles will look very familiar. Thats because theyre essentially the same code: django.contrib.staticfiles started its life as django-staticfiles and was merged into Django 1.3.
If youre upgrading from django-staticfiles, please see Upgrading from django-staticfiles, below, for a few minor changes youll need to make.
===== Using django.contrib.staticfiles =====
=== Basic usage ===
* Put your static files somewhere that staticfiles will find them.
* By default, this means within __static/ __subdirectories of apps in your INSTALLED_APPS.
Your project will probably also have static assets that** arent tied to a particular app**. The __STATICFILES_DIRS__ setting is a tuple of filesystem directories to check when loading static files. Its a search path that is by default empty. See the STATICFILES_DIRS docs how to extend this list of additional paths.
Additionally, see the documentation for the __STATICFILES_FINDERS__ setting for details on how staticfiles finds your files.
Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS.
For local development, if you are using runserver or adding staticfiles_urlpatterns to your URLconf, youre done with the setup your static files will automatically be served at the default (for newly created projects) STATIC_URL of /static/.
Youll probably need to refer to these files in your templates. The easiest method is to use the included context processor which allows template code like:
<img src="images/hi.jpg" />
See Referring to static files in templates for more details, including an alternate method using a template tag.
Deploying static files in a nutshell
When you're ready to move out of local development and deploy your project:
Set the STATIC_URL setting to the public URL for your static files (in most cases, the default value of /static/ is just fine).
Set the STATIC_ROOT setting to point to the filesystem path you'd like your static files collected to when you use the collectstatic management command. For example:
STATIC_ROOT = "/home/jacob/projects/mysite.com/sitestatic"
Run the collectstatic management command:
./manage.py collectstatic
This'll churn through your static file storage and copy them into the directory given by STATIC_ROOT.
Deploy those files by configuring your webserver of choice to serve the files in STATIC_ROOT at STATIC_URL.
Serving static files in production covers some common deployment strategies for static files.
Those are the basics. For more details on common configuration options, read on; for a detailed reference of the settings, commands, and other bits included with the framework see the staticfiles reference.
Note
In previous versions of Django, it was common to place static assets in MEDIA_ROOT along with user-uploaded files, and serve them both at MEDIA_URL. Part of the purpose of introducing the staticfiles app is to make it easier to keep static files separate from user-uploaded files.
For this reason, you need to make your MEDIA_ROOT and MEDIA_URL different from your STATIC_ROOT and STATIC_URL. You will need to arrange for serving of files in MEDIA_ROOT yourself; staticfiles does not deal with user-uploaded files at all. You can, however, use django.views.static.serve() view for serving MEDIA_ROOT in development; see Serving other directories.
Referring to static files in templates
At some point, you'll probably need to link to static files in your templates. You could, of course, simply hardcode the path to you assets in the templates:
<img src="http://static.example.com/static/myimage.jpg" />
Of course, there are some serious problems with this: it doesn't work well in development, and it makes it very hard to change where you've deployed your static files. If, for example, you wanted to switch to using a content delivery network (CDN), then you'd need to change more or less every single template.
A far better way is to use the value of the STATIC_URL setting directly in your templates. This means that a switch of static files servers only requires changing that single value. Much better!
Django includes multiple built-in ways of using this setting in your templates: a context processor and a template tag.
With a context processor
The included context processor is the easy way. Simply make sure 'django.core.context_processors.static' is in your TEMPLATE_CONTEXT_PROCESSORS. It's there by default, and if you're editing that setting by hand it should look something like:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
)
Once that's done, you can refer to STATIC_URL in your templates:
<img src="{{ STATIC_URL }}images/hi.jpg" />
If {{ STATIC_URL }} isn't working in your template, you're probably not using RequestContext when rendering the template.
As a brief refresher, context processors add variables into the contexts of every template. However, context processors require that you use RequestContext when rendering templates. This happens automatically if you're using a generic view, but in views written by hand you'll need to explicitly use RequestContext To see how that works, and to read more details, check out Subclassing Context: RequestContext.
Another option is the get_static_prefix template tag that is part of Django's core.
With a template tag
The more powerful tool is the static template tag. It builds the URL for the given relative path by using the configured STATICFILES_STORAGE storage.
{% load staticfiles %}
<img src="{% static "images/hi.jpg" %}" />
It is also able to consume standard context variables, e.g. assuming a user_stylesheet variable is passed to the template:
{% load staticfiles %}
<link rel="stylesheet" href="{% static user_stylesheet %}" type="text/css" media="screen" />
Note
There is also a template tag named static in Django's core set of built in template tags which has the same argument signature but only uses urlparse.urljoin() with the STATIC_URL setting and the given path. This has the disadvantage of not being able to easily switch the storage backend without changing the templates, so in doubt use the staticfiles static template tag.
Serving static files in development
The static files tools are mostly designed to help with getting static files successfully deployed into production. This usually means a separate, dedicated static file server, which is a lot of overhead to mess with when developing locally. Thus, the staticfiles app ships with a quick and dirty helper view that you can use to serve files locally in development.
This view is automatically enabled and will serve your static files at STATIC_URL when you use the built-in runserver management command.
To enable this view if you are using some other server for local development, you'll add a couple of lines to your URLconf. The first line goes at the top of the file, and the last line at the bottom:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# ... the rest of your URLconf goes here ...
urlpatterns += staticfiles_urlpatterns()
This will inspect your STATIC_URL setting and wire up the view to serve static files accordingly. Don't forget to set the STATICFILES_DIRS setting appropriately to let django.contrib.staticfiles know where to look for files additionally to files in app directories.
Warning
This will only work if DEBUG is True.
That's because this view is grossly inefficient and probably insecure. This is only intended for local development, and should never be used in production.
Additionally, when using staticfiles_urlpatterns your STATIC_URL setting can't be empty or a full URL, such as http://static.example.com/.
For a few more details on how the staticfiles can be used during development, see Static file development view.
Serving other directories
serve(request, path, document_root, show_indexes=False)
There may be files other than your project's static assets that, for convenience, you'd like to have Django serve for you in local development. The serve() view can be used to serve any directory you give it. (Again, this view is not hardened for production use, and should be used only as a development aid; you should serve these files in production using a real front-end webserver).
The most likely example is user-uploaded content in MEDIA_ROOT. staticfiles is intended for static assets and has no built-in handling for user-uploaded files, but you can have Django serve your MEDIA_ROOT by appending something like this to your URLconf:
from django.conf import settings
# ... the rest of your URLconf goes here ...
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
)
Note, the snippet assumes your MEDIA_URL has a value of '/media/'. This will call the serve() view, passing in the path from the URLconf and the (required) document_root parameter.
static(prefix, view='django.views.static.serve', **kwargs)
Since it can become a bit cumbersome to define this URL pattern, Django ships with a small URL helper function static() that takes as parameters the prefix such as MEDIA_URL and a dotted path to a view, such as 'django.views.static.serve'. Any other function parameter will be transparently passed to the view.
An example for serving MEDIA_URL ('/media/') during development:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Note
This helper function will only be operational in debug mode and if the given prefix is local (e.g. /static/) and not a URL (e.g. http://static.example.com/).
Serving static files in production
The basic outline of putting static files into production is simple: run the collectstatic command when static files change, then arrange for the collected static files directory (STATIC_ROOT) to be moved to the static file server and served.
Of course, as with all deployment tasks, the devil's in the details. Every production setup will be a bit different, so you'll need to adapt the basic outline to fit your needs. Below are a few common patterns that might help.
Serving the app and your static files from the same server
If you want to serve your static files from the same server that's already serving your site, the basic outline gets modified to look something like:
Push your code up to the deployment server.
On the server, run collectstatic to copy all the static files into STATIC_ROOT.
Point your web server at STATIC_ROOT. For example, here's how to do this under Apache and mod_wsgi.
You'll probably want to automate this process, especially if you've got multiple web servers. There's any number of ways to do this automation, but one option that many Django developers enjoy is Fabric.
Below, and in the following sections, we'll show off a few example fabfiles (i.e. Fabric scripts) that automate these file deployment options. The syntax of a fabfile is fairly straightforward but won't be covered here; consult Fabric's documentation, for a complete explanation of the syntax..
So, a fabfile to deploy static files to a couple of web servers might look something like:
from fabric.api import *
# Hosts to deploy onto
env.hosts = ['www1.example.com', 'www2.example.com']
# Where your project code lives on the server
env.project_root = '/home/www/myproject'
def deploy_static():
with cd(env.project_root):
run('./manage.py collectstatic -v0 --noinput')
Serving static files from a dedicated server
Most larger Django apps use a separate Web server -- i.e., one that's not also running Django -- for serving static files. This server often runs a different type of web server -- faster but less full-featured. Some good choices are:
lighttpd
Nginx
TUX
Cherokee
A stripped-down version of Apache
Configuring these servers is out of scope of this document; check each server's respective documentation for instructions.
Since your static file server won't be running Django, you'll need to modify the deployment strategy to look something like:
When your static files change, run collectstatic locally.
Push your local STATIC_ROOT up to the static file server into the directory that's being served. rsync is a good choice for this step since it only needs to transfer the bits of static files that have changed.
Here's how this might look in a fabfile:
from fabric.api import *
from fabric.contrib import project
# Where the static files get collected locally
env.local_static_root = '/tmp/static'
# Where the static files should go remotely
env.remote_static_root = '/home/www/static.example.com'
@roles('static')
def deploy_static():
local('./manage.py collectstatic')
project.rysnc_project(
remote_dir = env.remote_static_root,
local_dir = env.local_static_root,
delete = True
)
Serving static files from a cloud service or CDN
Another common tactic is to serve static files from a cloud storage provider like Amazon's S3 and/or a CDN (content delivery network). This lets you ignore the problems of serving static files, and can often make for faster-loading webpages (especially when using a CDN).
When using these services, the basic workflow would look a bit like the above, except that instead of using rsync to transfer your static files to the server you'd need to transfer the static files to the storage provider or CDN.
There's any number of ways you might do this, but if the provider has an API a custom file storage backend will make the process incredibly simple. If you've written or are using a 3rd party custom storage backend, you can tell collectstatic to use it by setting STATICFILES_STORAGE to the storage engine.
For example, if you've written an S3 storage backend in myproject.storage.S3Storage you could use it with:
STATICFILES_STORAGE = 'myproject.storage.S3Storage'
Once that's done, all you have to do is run collectstatic and your static files would be pushed through your storage package up to S3. If you later needed to switch to a different storage provider, it could be as simple as changing your STATICFILES_STORAGE setting.
For details on how you'd write one of these backends, Writing a custom storage system.
See also
The django-storages project is a 3rd party app that provides many storage backends for many common file storage APIs (including S3).
Upgrading from django-staticfiles
django.contrib.staticfiles began its life as django-staticfiles. If you're upgrading from django-staticfiles older than 1.0 (e.g. 0.3.4) to django.contrib.staticfiles, you'll need to make a few changes:
Application files should now live in a static directory in each app (django-staticfiles used the name media, which was slightly confusing).
The management commands build_static and resolve_static are now called collectstatic and findstatic.
The settings STATICFILES_PREPEND_LABEL_APPS, STATICFILES_MEDIA_DIRNAMES and STATICFILES_EXCLUDED_APPS were removed.
The setting STATICFILES_RESOLVERS was removed, and replaced by the new STATICFILES_FINDERS.
The default for STATICFILES_STORAGE was renamed from staticfiles.storage.StaticFileStorage to staticfiles.storage.StaticFilesStorage
If using runserver for local development (and the DEBUG setting is True), you no longer need to add anything to your URLconf for serving static files in development.
Learn more
This document has covered the basics and some common usage patterns. For complete details on all the settings, commands, template tags, and other pieces include in django.contrib.staticfiles, see the staticfiles reference.

View File

@@ -0,0 +1,83 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-24T20:24:00+08:00
====== Serving Static Media In Django Development Server ======
Created Monday 24 October 2011
http://www.muhuk.com/2009/05/serving-static-media-in-django-development-server/
There is a misconception about how static files (a.k.a media files) are handled in Django. Actually it is quite clearly documented here and here. Nevertheless a question about this comes up in the mailing-list or IRC channel frequently:
* Where do I put my media files?
* Django cant find my foo.gif!
* How can I link my CSS?
First of all, just to make it clear; just because **a server returns a response body with an internal URL doesnt necessarily mean it will be available on that server.** It is one thing that your templates produce the correct URL to a media file and another thing that your server actually serves that resource on that URL. **Django development server doesnt automagically serve media files1.**
===== Settings =====
There are three settings to get right: **MEDIA_ROOT, MEDIA_URL and ADMIN_MEDIA_PREFIX**. MEDIA_ROOT is the **absolute** filesystem path where your media files are. I usually set it like:
== MEDIA_ROOT ==
= os.path.join(os.path.abspath(os.path.dirname(__file__)), 'media')
This will set MEDIA_ROOT to point to the media directory in** your project directory**2. MEDIA_URL and ADMIN_MEDIA_PREFIX are **URLs**:
== MEDIA_URL ==
= '/media/' #定义media file的URL命名空间若为其它主机的URL则Django将__不能__为这些文件服务(因为客户浏览器会项指定的主机请求media file。)
== ADMIN_MEDIA_PREFIX ==
= '/media/admin/'
With this setup, to serve admin media in production, all I need to do is to **symlink **media folder of admin app into my media directory. Of course you can set MEDIA_URL to point to **another domain/subdomain**. Such as http://media.mydomain.com/. But this way you cant serve your media from development server.
===== URL Configuration =====
Add the following code snipplet at the end of your__ root __urls.py:
1 if settings.DEBUG:
2 from django.views.static import serve
3 _media_url = settings.MEDIA_URL
4 if _media_url.startswith('/'):
5 _media_url = _media_url[1:]
6 urlpatterns += patterns('',
7 (r'^%s(?P<path>.*)$' % _media_url,
8 serve,
9 {'document_root': settings.**MEDIA_ROOT**}))
10 del(_media_url, serve)
settings.DEBUG == True doesnt necessarily mean development server is running. But it is a good indicator since deploying with development server is not a good idea for many reasons. Notice here we dont serve media unless MEDIA_URL is an **absolute URL** on our server.
===== Templates =====
Finally we need to specify media URLs correctly. To avoid hard-coding media path we will be using__ { { MEDIA_URL } } __context variable in our templates. To have { { MEDIA_URL } } included automatically in each template we need to do two things:
* Make sure you have **django.core.context_processors.media **in your TEMPLATE_CONTEXT_PROCESSORS.
* Make sure each view is using a **RequestContext**.
Afterwards all we need to do is to specify our media URLs like this:
<img src="{ { MEDIA_URL } }img/header.jpeg" />
This will be translated to:
<img src="**/media/**img/header.jpeg" />
===== Bonus =====
While we are at it, why not serve our 500 and 404 pages statically. When DEBUG == True, 500 (server error) and 404 (not found) situations are handled with special debugging views. So theres no chance to test your error pages. Add the following code, just like static serving code:
1 if settings.DEBUG:
2 urlpatterns += patterns('',
3 (r'^404/',
4 'django.views.generic.simple.' \
5 'direct_to_template',
6 {'template': '404.html'}),
7 (r'^500/',
8 'django.views.generic.simple.' \
9 'direct_to_template',
10 {'template': '500.html'}))
Now when you visit /500/ and /404/ on your development server you will be served a fake error page.
1: There is an exception here. If you configured your settings correctly, development server will **serve admin media**.
2: Assuming your settings.py is directly inside your project directory, hence the __file__.

View File

@@ -0,0 +1,313 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-10-22T16:21:38+08:00
====== The staticfiles app ======
Created Saturday 22 October 2011
https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_STORAGE
New in Django 1.3: Please, see the release notes
**django.contrib.staticfiles **collects static files from each of your applications (and any other places you specify with STATICFILES_DIRS) into a** single location** that can easily be served** in production**.
django.contrib.staticfiles 的作用是将所有Web应用其静态文件位于statics和指定目录下的静态文件搜集到一个目录下以便于管理和使用。
=== See also ===
For an introduction to the static files app and some usage examples, see [[../Managing_static_files.txt|Managing static files]].
===== Settings =====
=== Note ===
The following settings control the behavior of the staticfiles app.
===== 1. STATICFILES_DIRS =====
Default: []
This setting defines the** additional locations **the staticfiles app will traverse if the **FileSystemFinder finder** is enabled, e.g. if you use the **collectstatic **or **findstatic** management command or use the __static file serving view__
注意Django__处理静态文件__时就是从STATICFILES_DIRS中列出的目录中查找,所以用Django处理静态文件时一定要指定该变量(可以不指定STATIC_ROOT)。
这个变量设置staticfiles应用将要搜索的额外目录(除了在INSTALLED_APPS中指定的应用的静态文件目录)
This should be set to a list or tuple of strings that contain full paths to your additional files directory(ies) e.g.:
**STATICFILES_DIRS = (**
** "/home/special.polls.com/polls/static",**
** "/home/polls.com/polls/static",**
** "/opt/webfiles/common",**
**)**
**默认情况下staticfiles将该目录中的所有静态文件放到STATIC_ROOT目录下指定Prefixes后可以将其放到子目录下。**
=== Prefixes (optional) ===
In case you want to refer to files in one of the locations with **an additional namespace**, you can optionally provide a prefix as (prefix, path) tuples, e.g.:
STATICFILES_DIRS = (
# ...
("downloads", "/opt/webfiles/stats"),
)
Example:
Assuming you have __STATIC_URL__ set '/static/', the **collectstatic** management command would **collect the "stats" files in a 'downloads' subdirectory of STATIC_ROOT**.
(collectstatic 管理命令会将/opt/webfiles/stats下的所有文件收集到STATIC _ROOT指定的绝对路径下的downloads目录中)
This would allow you to refer to the local file '/opt/webfiles/stats/polls_20101022.tar.gz' with '/static/downloads/polls_20101022.tar.gz' in your __templates__, e.g.:
<a href="{ { STATIC_URL } } downloads/polls_20101022.tar.gz">
===== 2. STATICFILES_STORAGE =====
**Default**: 'django.contrib.staticfiles.storage.StaticFilesStorage'
The **file storage engine **to use when collecting static files with the __collectstatic __management command.
这个变量指定了当用collectstatic管理命令将收集到的静态文件__统一存储__是使用的存储引擎(默认是存储到本地文件系统中)。
New in Django Development version.
A ready-to-use instance of the storage backend defined in this setting can be found at **django.contrib.staticfiles.storage.staticfiles_storage.**
For an example, see Serving static files from a cloud service or CDN.
===== STATICFILES_FINDERS =====
**Default:**
("django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder")
The list of **finder backends **that know how to **find static files in various locations**.
这个变量指定了collectstatic管理命令在收集文件时使用的**搜索后台**
The default will find files stored in the STATICFILES_DIRS setting (using django.contrib.staticfiles.finders.FileSystemFinder) and in a __static__ subdirectory of each app (using django.contrib.staticfiles.finders.AppDirectoriesFinder)
One finder is disabled by default: **django.contrib.staticfiles.finders.DefaultStorageFinder**. If added to your STATICFILES_FINDERS setting, it will look for static files in the default file storage as defined by the__ DEFAULT_FILE_STORAGE__ setting.
=== Note ===
When using the__ AppDirectoriesFinder __finder, make sure your apps can be found by staticfiles. Simply add the app to the __INSTALLED_APPS__ setting of your site.
Static file finders are currently considered a private interface, and this interface is thus undocumented.
===== Management Commands =====
django.contrib.staticfiles exposes three management commands.
==== collectstatic ====
**django-admin.py collectstatic**
Collects the static files into__ STATIC_ROOT__.
注意一旦执行该命令APP的static目录以及其中的所有文件都会被移动到STATIC_ROOT目录中。因此若用Django处理静态文件有两种方式
1. 如果没有执行collectstatic命令即所有的静态文件都放在APP/static目录下
在INSTALLED_APPS中加入**django.contrib.staticfiles , **这样Django查找静态文件时会查找所有APP/static目录同时查找STATICFILES_DIRS中指定的目录。
2. 如果执行了collectstatic命令所有APP的static文件都会移动到STATIC_ROOT下
1). 将当前project目录加入到INSTALLED_APPS中这样Django会找到它下的static目录。
2)或者将project下的static目录加入到STATICFILES_DIRS中但是这只能用于开发、调试且不能再执行colletcstatic命令(因为STATIC_ROOT和STATICFILES_DIRS包含相同的文件目录)。
Duplicate file names are by default resolved in a similar way to how template resolution works: the file that is __first found__ in one of the specified locations will be used. If you're confused, the__ findstatic__ command can help show you which files are found.
Files are searched by using the enabled **finders.** The default is to look in all locations defined in __STATICFILES_DIRS__ and in the '__static'__ directory of apps specified by the INSTALLED_APPS setting.
== New in Django Development version. ==
The collectstatic management command calls the post_process() method of the STATICFILES_STORAGE after each run and passes a list of paths that have been found by the management command. It also receives all command line options of collectstatic. This is used by the CachedStaticFilesStorage by default.
Some commonly used options are:
--noinput
Do NOT prompt the user for input of any kind.
-i <pattern>
--ignore <pattern>
Ignore files or directories matching this glob-style pattern. Use multiple times to ignore more.
-n
--dry-run
Do everything except modify the filesystem.
-c
--clear
New in Django Development version.
Clear the existing files before trying to copy or link the original file.
-l
--link
Create a symbolic link to each file instead of copying.
--no-post-process
New in Django Development version.
Don't call the post_process() method of the configured STATICFILES_STORAGE storage backend.
--no-default-ignore
Don't ignore the common private glob-style patterns 'CVS', '.*' and '*~'.
For a full list of options, refer to the commands own help by running:
**$ python manage.py collectstatic --help**
===== findstatic =====
django-admin.py findstatic
Searches for one or more relative paths with the enabled** finders**.
For example:
$ python manage.py findstatic css/base.css admin/js/core.js
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
/home/polls.com/src/django/contrib/admin/media/js/core.js
By default, all matching locations are found. To only return the first match for each relative path, use the --first option:
$ python manage.py findstatic css/base.css --first
/home/special.polls.com/core/static/css/base.css
This is a debugging aid; it'll show you exactly which static file will be collected for a given path.
===== runserver =====
django-admin.py runserver
Overrides the **core runserver **command(./manager.py runserver) if the staticfiles app is installed and adds **automatic serving of static files** and the following new options.
注意:**django默认是不提供静态文件存取服务**的(这是web server的功能),它只提供动态页面的生成服务。
--nostatic
Use the --nostatic option to disable serving of static files with the staticfiles app entirely. This option is only available if the staticfiles app is in your project's INSTALLED_APPS setting.
== Example usage: ==
django-admin.py runserver --nostatic
--insecure
Use the --insecure option to force serving of static files with the staticfiles app even if the __DEBUG setting is False__. By using this you acknowledge the fact that it's grossly__ inefficient and probably insecure__. This is only intended for local development, should never be used in production and is only available if the staticfiles app is in your project's INSTALLED_APPS setting.
Example usage:
django-admin.py runserver --insecure
===== Storages =====
**StaticFilesStorage**
class storage.StaticFilesStorage
A subclass of the** FileSystemStorage** storage backend that uses the __STATIC_ROOT__ setting as the base file system location and the __STATIC_URL__ setting respectively as the **base URL**.
** post_process(paths, **options)**
== New in Django Development version. ==
This method is called by the __collectstatic__ management command after each run and gets passed the paths of found files, as well as the command line options.
The CachedStaticFilesStorage uses this behind the scenes to replace the paths with their hashed counterparts and update the cache appropriately.
**CachedStaticFilesStorage**
class storage.CachedStaticFilesStorage
== New in Django Development version. ==
A subclass of the__ StaticFilesStorage__ storage backend which caches the files it saves by **appending the MD5 hash of the file's content to the filename**. For example, the file **css/styles.css **would also be saved as **css/styles.55e7cbb9ba48.css.**
The purpose of this storage is to **keep serving the old files** in case some pages still refer to those files, e.g. because they are cached by you or a 3rd party proxy server. Additionally, it's very helpful if you want to apply far future Expires headers to the deployed files to speed up the load time for subsequent page visits.
The storage backend automatically **replaces the paths found in the saved files matching other saved files with the path of the cached copy **(using the post_process() method).
The regular expressions used to find those paths (django.contrib.staticfiles.storage.CachedStaticFilesStorage.cached_patterns) by default cover the @import rule and url() statement of Cascading Style Sheets. For example, the 'css/styles.css' file with the content
@import url("../admin/css/base.css");
would be replaced by calling the url() method of the CachedStaticFilesStorage storage backend, ultimatively saving a 'css/styles.55e7cbb9ba48.css' file with the following content:
@import url("/static/admin/css/base.27e20196a850.css");
To enable the CachedStaticFilesStorage you have to make sure the following requirements are met:
* the __STATICFILES_STORAGE__ setting is set to 'django.contrib.staticfiles.storage.CachedStaticFilesStorage'
* the DEBUG setting is set to False
* you use the staticfiles static template tag to refer to your static files in your templates
* you've collected all your static files by using the collectstatic management command
Since creating the MD5 hash can be a performance burden to your website during runtime, staticfiles will automatically try to cache the hashed name for each file path using Django's caching framework. If you want to override certain options of the cache backend the storage uses, simply specify a custom entry in the CACHES setting named 'staticfiles'. It falls back to using the 'default' cache backend.
===== Template tags =====
**static**
== New in Django Development version. ==
Uses the configued S__TATICFILES_STORAGE __storage to create the full URL for the given relative path, e.g.:
{% load static from staticfiles %}
<img src="{% static "css/base.css" %}" />
The previous example is equal to calling the url method of an instance of STATICFILES_STORAGE with "css/base.css". This is especially useful when using a non-local storage backend to deploy files as documented in Serving static files from a cloud service or CDN.
==== Other Helpers ====
There are a few other helpers outside of the staticfiles app to work with static files:
* The django.core.context_processors.static() context processor which adds__ STATIC_URL__ to every template context rendered with RequestContext contexts.
* The builtin template tag__ static __which takes a path and urljoins it with the static prefix STATIC_URL.
* The builtin template tag __get_static_prefix__ which populates a template variable with the static prefix STATIC_URL to be used as a variable or directly.
* The similar template tag__ get_media_prefix__ which works like get_static_prefix but uses MEDIA_URL.
===== Static file development view =====
**django.contrib.staticfiles.views.serve(request, path)**
This view function serves static files in development.
===== Warning =====
This view will only work if **DEBUG is True**.
That's because this view is grossly inefficient and probably insecure. This is only intended for** local development**, and should never be used in production.
This view is **automatically enabled by runserver** (with a DEBUG setting set to True). To use the view with a different local development server, add the following snippet to the end of your primary URL configuration:
**from django.conf import settings**
**if settings.DEBUG:**
** urlpatterns += patterns('django.contrib.staticfiles.views',**
** url(r'^static/(?P<path>.*)$', 'serve'),**
** )**
Note, the beginning of the pattern (r'^static/') should be your __STATIC_URL__ setting.
Since this is a bit finicky, there's also a helper function that'll do this for you:
**django.contrib.staticfiles.urls.staticfiles_urlpatterns()**
This will return the proper URL pattern for serving static files to your already defined pattern list. Use it like this:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# ... the rest of your URLconf here ...
urlpatterns += staticfiles_urlpatterns()
Warning
This helper function will only work if DEBUG is True and your STATIC_URL setting is neither empty nor a full URL such as http://static.example.com/.