@hpp157
2016-08-18T04:27:38.000000Z
字数 7066
阅读 2430
Django
本章最后的模板部分代码已经上传到github,需要的可以下载:download
从Django框架诞生以来,数目众多的其他web框架也在很多开源社区出现。如专注前端的框架如Angular.js
,Ember.js
以及Backbone.js
在Javascript社区出现,并且成为现代web框架的领跑者.Django在哪一块适应了这些呢?我们怎样把这些MVC框架融入到Django的核心框架中呢
本书教你怎样利用Django粉丝所谓的“内置电池(batteries included)”哲学的优点。指导你走出“对于快速发展的应用开发来说,Django太重(重型框架)的误区”。从构建一个世界上最小的Django程序的目标出发来写一个RESTFULL
API,让你了解这款流行的python WEB 开发框架的优点
ubuntu 16.04
安装pip
sudo wget https://bootstrap.pypa.io/get-pip.py --no-check-certificate
sudo python get-pip.py
安装Django 1.9.9
sudo pip installl django==1.9.9
许多新的语言都是以hello world
的例子作为开始,我们用flask
社区的hello world
的例子来展示这个微型框架是怎么的一个微型
本章,我们使用单个文件hello.py
开始,这个文件将会包括我们的django
项目的所有代码,我们需要建一个view来处理根路径(root URL)
以及对项目做些必要的设置
Django被称为(referred to as)一个MTV框架model-template-view
.这个view
端口一般看作存放HTTP
请求的进入
和查询
,结构
,以及输出到展示层所必须的数据
的地方
在我们的hello.py
这个例子中,让我们创建一个简单的方法来执行hello,world
的相应
from django.http import HttpResponse
def index(request):
return HttpResponse('hello,world')
在一个大的项目中,这应该在你的apps
里的views.py
文件里面,但是本教程并不要求这样,这样做仅仅是一个惯例而已
为了把我们的view和网站结构联系起来,我们需要用一个url
将view
联系起来,在这个例子中,根目录可以独自处理view。Django
关联一个views
和URL
通过正则表达式
匹配url
,以及任意可调用的参数到view
中
from django.conf.urls import url
from django.http import HttpResponse
def index(request):
return HttpResponse('hello,world')
urlpatterns =(
url(r'^$',index),
)
现在,这个文件结合了views.py
和路径urls.py
。再次强调下,把URL pattern
放到urls.py
文件中不是必须的,它们可以存在于python任何重要的模块中
设置包括数据库
,缓存
,语言
,静态资源
,上传路径
等设置。对于新的开发者来说,django
的设置是一个难点,虽然新版本已经缩减了设置文件的长度
这个例子将在debug
模式下运行,除了这,django
仅仅需要设置项目路径在哪儿可以找到以及在那个模块中使用定义过urlpatterns
变量。在hello.py
例子中,当前模块的root URLS
会使用前一节定义过的urlpatterns
from django.conf import settings
settings.configure(
DEBUG = True,
SECRET_KEY ='thisisthesesecretkey',
ROOT_URLCONF = __name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XframeOptionsMiddleware'
),
)
这个例子中包括了一个专门的
SECRET_KEY
设置,这个设置不能用于生产环境,一个安全密钥必须由默认的session
以及跨域访问保护
生成。
我们需要在模块从django
导入之前进行设置。通常,这些设置包含在专门的settings.py
中,这个settings.py
文件通过默认的startproject
命令自动创建,自动创建的会包含一些其他的设置。
让我们看下例子运行起来是什么样子把,一个典型的django
项目包含一个manage.py
文件,它用来运行各种各样的命令,比如创建数据库的表以及运行服务器。这个文件本身只有10行代码。我们会把manage.py
的功能添加到`hello.py'中
import sys
from django.conf import settings
settings.configure(
DEBUG = True,
SECRET_KEY ='thisisthesesecretkey',
ROOT_URLCONF = __name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware'
),
)
from django.conf.urls import url
from django.http import HttpResponse
def index(request):
return HttpResponse('hello,world')
urlpatterns =(
url(r'^$',index),
)
#manage.py的功能
if __name__ == '__main__':
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
现在你可以同过命令行运行例子了
$ python hello.py runserver
打开浏览器访问http://localhost:8000
或者输入127.0.0.1:8000
这个例子展示了django
的基础功能,写view
,设置seting
,运行管理命令。从本质上来说,django是一个python语言的web框架,处理客户端过来的http request
以及向客户端返回http response
,至于中间怎么做,完全取决于你自己
Django还提供额外的工具来处理HTTP
请求的日常任务,比如html
文件的渲染,表单数据的解析
以及session
状态的持久化。理解这些功能对于让你的程序变的轻量是非常重要的。通过这样,你可以全面理解Django框架获得真正的技能。
目前,我们的hello,world
项目通过命令行的命令runserver
来运行,这是一个基于标准库之上的socket server
,它对于本地环境开发非常有帮助,但不适合生产环境,会引起一些安全问题
WSGI
是用来具体说明让web服务器http和应用web框架比如Django
之间如何交流的。它通过PEP333以及改进的PEP333定义。web服务器有非常多种,比如apache
,Gunicorn
,uWSGI
,CherryPy
,Tornado
以及Chaussette
等
每一个服务器都需要定义一个符合WSGI
接口的程序来使用,django
有一个很容易使用的接口,用法就是通过get_wsji_application
来创建这个应用。
...
from django.conf.urls import url
from django.core.wsgi import get_wsgi_application
from django.http import HttpResponse
application = get_wsgi_application()
if __name__ == '__main__':
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
正常情况下,这些应该保存在通过startproject
命令创建项目时自动生成的wsgi.py
的文件中。至于这个叫做application
的名字,它只是个惯例,大多数的WSGI
服务器都这么叫。每个服务器都可以通过配置文件更改这个名字。
现在我们的符合WSGI
接口的程序弄好了,就等着一个WSGI
服务器了。Gunicorn
是一个比较流行的WSGI
服务器,它可以通过PIP
命令来安装
sudo pip install gunicorn
gunicorn
安装之后,你可以通过命令行运行它
gunicorn hello --log-file=-
打开浏览器,输入localhost:8000
就可以看到程序再次运行起来了
虽然Gunicorn
是为生产环境准备的一个服务器,但是程序现在还不能部署到生产环境,生成环境需要关闭DEBUG
模式,SECRET_KEY
也不能被这么明显的看到,应该随机生成并且进行加密来保证安全。
这就导致Django社区产生一个问题,在一个项目中怎样来管理不同的开发阶段,不同的生产环境的设置。社区也有很多的办法,比如把settings.py
转换成一个包,来为每一个环境创建一个设置模块,但是,我们这个项目并不适合这样做。
十二要素应用(The Twelve-Factor App)主张web应用应该从环境变量里获取其配置。 这一实践很快被现代PaaS服务采用以用于允许简单的配置变更。
我们把这一方法应用到项目中,只需要进行设置DEBUG
和SECRET_KEY
这两个需要改变的值就可以了。
import os
import sys
from django.conf import settings
DEBUG = os.environ.get('DEBUG', 'on') == 'on'
SECRET_KEY = os.environ.get('SECRET_KEY', os.urandom(32))
settings.configure(
DEBUG=DEBUG
, SECRET_KEY=SECRET_KEY
, ROOT_URL_CONF=__name__
, MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware'
),
)
你可能会注意到,默认的DEBUG
是开启的,并且SECRET_KEY
会在程序每次启动的时候重新随机生成一个。我们这个小项目自然无碍,但是假入碰到程序需要SECRET_KEY
保持稳定的情况,比如signed cookies
,会导致程序频繁失效。
让我们启动下程序来测试一下上面的设置,将DEBUG
默认的开启改为关闭,我们需要设置DEBUG
的环境变量为off,在unix系统中,如linux
,OSX
(现在叫 mac OSX),或者FreeBSD
,环境变量通过命令行中的export
命令来设置。要是window
的话,用set
hunter@hunter:~$ export DEBUG=off
hunter@hunter:~$ python hello.py runserver
CommandError: You must set setting.ALLOWED_HOSTS if DEBUG if false
你会发现出错了,我们的程序中没有设置ALLOWED_HOSTS
。加入你打网站是example.com
,那么你应该只允许接收example.com
这个客户端发送过来的请求,如果ALLOWED_HOSTS
环境没有设置的话,就只允许localhost
访问:
import os
import sys
from django.conf import settings
DEBUG = os.environ.get('DEBUG', 'on') == 'on'
SECRET_KEY = os.environ.get('SECRET_KEY', os.urandom(32))
#添加ALLOWED_HOSTS设置
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS','localhost').split('.')
settings.configure(
DEBUG=DEBUG
, SECRET_KEY=SECRET_KEY
, ROOT_URL_CONF=__name__
, MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware'
),
)
这该我们提供了一种通过修改环境变量来改变设置的方式。我们可以用unset
命令来去掉环境变量
hunter@hunter:~$ unset DEBUG
目前为止,我们的项目集中在重新考虑通过startproject
命令自动创建的文件布局上了。这条命令也可以允许你指定一个模板来提供布局,startproject
创建的模板是一个目录或者压缩文件当命令运行时会把这个目录或者压缩文件渲染为template
.渲染时会将project_name
,project_directory
,secret_key
和docs_verson
这四个变量渲染进去。我们把hello.py
文件转换为一个项目模板,里面的一些相关部分要替换为变量,这里把密钥的值替换为secret_key
:
import os
import sys
from django.conf import settings
DEBUG = os.environ.get('DEBUG', 'on') == 'on'
SECRET_KEY = os.environ.get('SECRET_KEY', '{{ secret_key }} ')
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', 'localhost').split('.')
settings.configure(
DEBUG=DEBUG
, SECRET_KEY=SECRET_KEY
, ROOT_URL_CONF=__name__
, MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware'
),
)
from django.conf.urls import url
from django.core.wsgi import get_wsgi_application
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello world')
urlpatterns = (
url(r'^$', index),
)
application = get_wsgi_application()
if __name__ == '__main__':
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
现在,我们把文件保存为project_name.py
放到一个project_name
的目录中,比如 hello
项目:
hello/
project_name/
project_name.py
接着运行下面命令
django-admin.py startproject hello --template=project_name
运行和目录如下:
hello/
project_name/
project_name.py
hello/
hello.py
如之前的例子一样,我们可以不用startprojecct
命令来创建我们的项目,自动生成的文件布局并不是适合所有的项目,--template
这个参数选项你可以使用也可不使用。
Django内置的有一个模板引擎,和关系对象映射(ORM),并且免费使用。这些你可以使用,也可自己扩展,这些都是自由的。下一章我们会扩展单文件例子,提供一个简单的HTTP服务以及使用更多的内置工具。