全面解读Python Web开发框架Django,利用Django构建web应用及其部署

全面解读Python Web开发框架Django

Django是一个开源的Web应用框架,由Python写成。采用MVC的软件设计模式,主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don’t Repeat Yoursef)。
 

花了两周时间,利用工做间隙时间,开发了一个基于Django的项目任务管理Web应用。项目计划的实时动态,能够方便地被项目成员查看(^_^又 重复发明轮子了)。从前台到后台,好好折腾了一把,用到:HTML、CSS、JavaScript、Apache、Python、mod_wsgi、 Django。很久不用CSS和JavaScript了,感到有点生疏了,查了无数次手册。后台Django开发环境的搭建也花了很多时间和精力。记录下 来,省得之后走弯路。同时给你们推荐一下Django框架,若是你想很是快速地编写本身的web应用,能够考虑使用Django,同时Django还会给 你提供一个功能强大的后台管理界面。php

Django是一个开源的Web应用框架,由Python写成。采用MVC的软件设计模式,主要目标是使得开发复杂的、数据库驱动的网站变得简单。 Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don't Repeat Yoursef)。在Django中Python被广泛使用,甚至包括配置文件和数据模型。它能够运行在启用了mod_python或mod_wsgi的 Apache2,或者任何兼容WSGI(Web Server Gataway Interface)的Web服务器。css

1. Django的快速开发html

第一步(Model):设计本身的数据模型。
第二步(View):建立网页模板。Django本身的Html模板语言,很是容易将数据和模板结合起来,建立动态页面。
第三步(Control):定义URL,提供服务和控制。
入门教程: https://docs.djangoproject.com/en/1.4/intro/tutorial01/前端

2. Django开发环境的搭建python

Django能够运行在任何遵照WSGI的Web服务器上。本文主要介绍Apache2+mod_wsgi+Django的环境搭建。所须要的软件以下:mysql

Apache2:Web服务器
Python2.x:Python语言支持
mod_wsgi:Apache的WSGI模块,有了该模块的支持,就能够用Python作为CGI脚原本编写网络应用(以前还有一个 mod_python,在Apache官网上发现mod_python已通过时,渐渐要被mod_wsgi替代,听说mod_wsig性能要好一些)
Django:一个强大的Python Web开发框架,本文的主角。
2.1 Apache的安装nginx

下 载: http://httpd.apache.org/download.cgi  (选择版本2.2.22,mod_wsig暂不支持2.4.2)git

解压缩 : $tar xvfz httpd-NN.tar.gzgithub

$cd httpd-NNweb

编译配置: $./configure –with-included-apr –prefix=PREFIX #with-included-apr选项指定使用apache软件包里面的apr库

编 译: $make

安 装: $make install

配 置: $vim PREFIX/conf/httpd.conf

测 试: $PREFIX/bin/apachectl -k start

参 考:

官方主页: http://httpd.apache.org/
安装文档: http://httpd.apache.org/docs/2.2/install.html
2.2 Python的安装

下 载: http://www.python.org/getit/releases/2.7.3/ (选择2.X版均可以,3.0暂不支持)

解压缩 : $tar xvf python-X.tar

$cd python-Y

编译配置: $./configure –enable-shared –prefix=PREFIX #–enable-shared选项指定生成python的动态库

编 译: $make

安 装: $make install

测 试: $python

参 考:

官方主页: http://www.python.org/
2.3 mod_wsgi模块的安装

下 载: http://code.google.com/p/modwsgi/  (选择3.3版本)

解压缩 : $tar xvfz mod_wsgi.X.Y.tar.gz

$cd mod_wsgi.X.Y

编译配置: $././configure –with-apxs=/usr/local/apache2/bin/apxs –with-python=/usr/local/bin/python # 指定Apache2的模块编译程序和Python解析器

编 译: $make

安 装: $make install

测 试: $python

2.3.1  配置Apache(修改/usr/local/apche2/confi/httpd.conf)

?
1
2
3
4
5
6
7
8
9
# 加载wsgi模块
LoadModule wsgi_module modules/mod_wsgi.so
....
# HTTP请求处理脚本
WSGIScriptAlias /test /home/xxx/www/test.wsgi
< Directory "/home/xxx/www">
Order allow, deny
Allow from all
</ Directory >

2.3.2 编写test.wsgi(WSGI标准: http://www.python.org/dev/peps/pep-3333/

?
1
2
3
4
5
6
7
8
9
def application(environ, start_response):
  status = '200 OK'
  output = 'Hello World!'
 
  response_headers = [( 'Content-type' , 'text/plain' ),
    ( 'Content-Length' , str ( len (output)))]
  start_response(status, response_headers)
 
  return [output]

2.3.3  重启apche2

在任意网络浏览器中输入:http://www.mysite.com/test。看到“Hello World!”,恭喜你成功安装了WSGI模块。

参 考:

官方主页: http://code.google.com/p/modwsgi/
安装文档: http://code.google.com/p/modwsgi/wiki/QuickInstallationGuide
配置文档: http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide
WSGI文档: http://www.python.org/dev/peps/pep-3333/

2.4 Django的安装

下 载: https://www.djangoproject.com/download/  (选择1.4版本)

解压缩 : $tar xvfz Django-1.4.tar.gz

$cd Django-1.4

安 装: $python setup.py install

测 试:

?
1
2
3
$python
>>> import django
>>> print (django.get_version())

参 考:

官方主页: https://www.djangoproject.com/
安装文档: https://docs.djangoproject.com/en/1.4/intro/install/
快速入门: https://docs.djangoproject.com/en/1.4/intro/tutorial01/

3. Django中文支持

Django使用的是UTF-8编码,因此对于国际化支持不成问题。由于初次玩Django,中文显示乱,折腾死人了(一直在用的的mysql默认 字符串是latin1编码,vim默认保存的文件编码为ascii)。最终得出结论,若是中文显示乱码,或者Django报错(… unicode …blabla…),请检查:

Django的设置。打开本身项目的settings.py,LANGUAGE_CODE=”zh_CN” ?FILE_CHARSET='UTF-8′ ?DEFAULT_CHARSET='utf-8′?
查看本身项目全部的文件编码是否以UTF-8编码保存的?确保.py文件第一行要加上:#-*-  coding:utf-8 -*- ?
HTML模板文件head部分,添加<meta http-equiv=“Content-Type” content=“text/html;charset=utf-8″/>
检查本身项目的数据库字符串编码是否为UTF-8,命令以下:
查看:

?
1
2
3
show create database dbname;
show create table tablename;
show full columns from tablename;

建立:

?
1
2
create database dbname CHARACTER SET utf8;
create table tblname CHARACTER SET utf8;

修改:

?
1
2
alter database dbname CHARACTER SET = utf8;
alter table tablename CONVERT TO CHARACTER SET utf8;

4. Django应用的部署

Django应用的运行有两个方式,一种是在开发阶段,使用建立项目下面的manager.py runserver ip:port来启动一个用Python实现的轻型web服务器;另一种就是经过mod_wsgi将你本身的应用部署到生产环境,对外提供服务。下面简 单介绍一下Django的部署(虚拟主机上的配置,自行参考文档)。

假设你建立的Django项目文件列表以下:

?
1
2
3
4
5
6
7
8
9
10
11
my-site
|- my-site
|- myapp
  |-static
  |- ...
|- static
  |- css
  |- js
  | ...
|- apache
|- ...

4. 1. 建立Django项目的wsgi脚本(my-site/apache/django.wsgi),内容以下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import os, sys
 
sys.path.append( '/.../www/' )
sys.path.append( '/.../www/my-site' )
os.environ[ 'DJANGO_SETTINGS_MODULE' ] = 'my-site.settings'
os.environ[ 'PYTHON_EGG_CACHE' ] = '/.../www/.python-eggs'
 
import django.core.handlers.wsgi
 
_application = django.core.handlers.wsgi.WSGIHandler()
 
def application(environ, start_response):
   if environ[ 'wsgi.url_scheme' ] = = 'https' :
     environ[ 'HTTPS' ] = 'on'
   return _application(environ, start_response)

4.2. 配置Apache(httpd.conf),内容以下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 请求访问www.xxx.com/的时候,转到django.wsgi
WSGIScriptAlias / /.../www/my-site/apache/django.wsgi
 
<Directory /.../www/my-site/apache>
Order deny,allow
Allow from all
</Directory>
 
# 静态文件的访问路径配置
Alias /static/ /.../www/my-site/static/
 
<Directory /.../www/my-site/static>
Order deny,allow
Allow from all
</Directory>

4.3. 配置setting.py

EBUG=False
自定义404.html,500.html模板(网页未找到、服务器内部错误)

4.4. 静态文件

?
1
2
3
STATIC_ROOT = ‘/…/www/my-site/static/'
STATIC_URL = ‘/static/'
$./manager.py collectstatic

注意:开发阶段,通常都会把相应app的静态文件,放在app目录下的static目录下。在正式生产环境部署的时候,使用./manager.py collectstatic来把全部静态文件收集到STATIC_ROOT指定的位置,包括管理后台的。

4.5. 重启apahce

浏览器输入相应的URL地址,看到你本身的web应用界面的话,恭喜大功告成!

5. 总结

本文主要介绍了一下Django开发环境的搭建、Django应用的部署和中文乱码的解决方法。具体如何使用Django快速地建立本身的web应 用,并无说起。Django相对来讲,文档比较齐全,加上官方推出的一本书:《The Django Book》,相信只要开发环境搭建好,建立本身的Web应用也会很是容易。

进一步学习Django,请看:

Django1.4文档: https://docs.djangoproject.com/en/1.4/
Django Book 英文版: http://www.djangobook.com/en/2.0/
Django Book 中文版: http://djangobook.py3k.cn/2.0/

 

 

 

 

 

 

利用Django构建web应用及其部署 

推荐两个很是好的教程:

The Django Book(中文版):我本身一开始是参考这个教程学习的,很是有意思的是这个教程中有大量的评论,几乎每段都有,从10年开始一直到如今。虽然这本书比较老,有不少内容都过期了,但在这些评论中有讲解,有勘误和最新的实践,这些评论让整个学习过程变得很是有趣。我本身也留下了很多评论,哈哈。

被解放的姜戈:这是博客园的另外一位博友Vamei(中文读做,挖煤)写的关于Django简介的系列文章,基本概念,简单的实践都有。

 

建立一个名为mysite的Django项目的命令:

$ django-admin startproject mysite

$ cd mysite

$ python manage.py startapp myApp  # 建立一个app,名称为myApp

 

一个刚建立的Django项目的目录结构

图1:django项目的基本结构

 

不是要点的要点


  1. 建立一个专门的用户,例如www-data:在后面部署Django的过程当中,我遇到了自使用Linux以来,最多的权限问题。很大的缘由是由于不一样进程间须要通讯,或相互访问,这就须要这些用户间都有某个文件的读写权限。例如两个进程都要访问同一个socket文件时,这两个进程的用户都要对该socket文件有读写权限。所以将全部这些进程都交给一个专门的用户来操做,能够避免不少权限问题。
  2. url是web开发的核心要素之一:在客户端,每个url就是一个页面;从开发者来看,全部的开发都是围绕如何正确的路由这些url到正确的html文件来展开的。
  3. stackoverflow是一个很棒的网站,大部分的问题均可以在上面找到解决方案,若是没有找到答案,就提问吧,很快就能够获得回复。

 

 

概述


用户从浏览器访问一个django开发的页面,整个流程是这样的:

the web client <-> the web server <-> the socket <-> WSGI <-> Django

 

用户从浏览器访问一个url,该请求从用户发送到web server,web server经过socket(或者约定一个端口)与WSGI进行通讯,再由WSGI将请求发给django。web server和WSGI都有不少种选择,常见的组合有Apache + mod_wsgi和nginx + uWSGI。我用的是nginx + uWSGI。下面先介绍几个名词。

 

web server

虽然每一个网页服务器程序有不少不一样,但有一些共同的特色:每个网页服务器程序都须要从网络接受HTTP请求,而后提供HTTP回复给请求者。HTTP回复通常包含一个HTML文件,有时也能够包含纯文本文件、图像或其余类型的文件。

通常来讲这些文件都存储在网页服务器的本地文件系统里,而URL和本地文件名都有一个阶级组织结构的,服务器会简单的把URL对照到本地文件系统中。当正确安装和设置好网页服务器软件,服务器管理员会从服务器软件放置文件的地方指定一个本地路径名为根目录。

web server是面对用户请求的第一道门,有些请求由web server本身处理,例如静态文件的访问等;还有一些请求则交给WSGI处理,如对动态页面的访问。

 

socket: 最近在学习《计算机网络》这门课,socket相关的内容在网络模型中属于传输层,位于网络层和应用层之间。主要用于实现进程间通信。在这里主要是实现nginx和uWSGI两个不一样进程之间的通信。

 

WSGI:

Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来之后,许多其它语言中也出现了相似接口。

能够将WSGI看作是一种协议,听说之因此Python中有不少web框架,就是由于WSGI调用很是方便。uWSGI是WSGI这一协议的实现。在实际使用过程当中,uWSGI代替了python manage.py runserver的做用,固然还有其余做用。

最先的Web服务器只支持静态html。随着网站也愈来愈复杂,出现了动态技术。可是服务器并不能直接运行 php,asp这样的文件,所以须要一个第三方,与第三方作个约定,我把请求参数发送给你,而后我接收你的处理结果给客户端。这个约定就是 common gateway interface,简称cgi。这个协议能够用vb,c,php,python 来实现。

简单地说,cgi是Web App与Http Server之间的桥梁。

除了cgi,还有wsgi(Web Service Gateway Interface)。WSGI所在层的位置低于CGI,与CGI不一样的是WSGI具备很强的伸缩性且能运行于多线程或多进程的环境下,这是由于WSGI只是一份标准并无定义如何去实现。实际上WSGI并不是CGI,由于其位于web应用程序与web服务器之间,而web服务器能够是CGI。

 

 

全部均开始于settings文件


若是咱们已经建立了一个hello应用(如何建立,请参考本文开始时提到的两个教程),而且使用下面的语句运行:

python manage.py runserver 0.0.0.0:8000

 

那么,当咱们访问 http://192.168.1.100:8000/hello/ 时(前面是一个局域网内的ip,8000是端口号),发生了什么?
 
全部均开始于settings文件。当你运行python manage.py runserver,脚本将在于manage.py同一个目录下查找名为setting.py的文件。这个文件包含了全部有关这个Django项目的配置信息(都是大写的变量名称,例如 TEMPLATE_DIRS、DATABASE_NAME等)。最重要的设置是ROOT_URLCONF,它将做为URLconf告诉Django在这个站点中哪些Python的模块将被用到。
 
打开文件settings.py你将看到以下内容:
ROOT_URLCONF = 'mysite.urls'

 

相对应的文件是mysite/urls.py
 
当访问URL /hello/ 时,Django根据ROOT_URLCONF的设置装载URLconf 。而后按顺序逐个匹配URLconf里的URLpatterns,直到找到一个匹配的。当找到这个匹配的URLpatterns就调用相关联的view函数,并把HttpRequest对象做为第一个参数(一个视图功能必须返回一个HttpResponse)。一旦作完,Django将完成剩余的工做:转换Python的对象到一个合适的带有HTTP头和body的Web Response(例如,网页内容)。
 
从http requese到http response是经过下面的过程实现的:
 
访问请求 -> setting.py -> urls.py -> views.py -> hello()
 
复制代码
# urls.py


from django.conf.urls import url, include
from django.contrib import admin
from mysite.views import hello

admin.autodiscover()


urlpatterns = [
    url(r'^hello/$', hello),
]
复制代码

 

复制代码
# viwes.py

from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello World!")
复制代码

 

 

uWSGI与Django之间的通信


uWSGI与Django之间的通信是经过wsgi.py文件实现的,这个文件在建立Django project后就生成了。这里的设置中最主要的一点就是正确的指出settings.py文件的位置。由于Django中的一切都始于这个文件。这些都使用Django的默认配置就能够了。

复制代码
# wsgi.py
""" WSGI config for mysite project. It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/ """ import os from django.core.wsgi import get_wsgi_application # 这里已经指定了settings文件的位置 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") application = get_wsgi_application()
复制代码

 

一些命令:

# 安装uwsgi

$ pip install uwsgi 

 

# 若是 python manage.py runserver 0.0.0.0:8000 能够运行成功,则可使用下面的命令代替django自己的runserver功能(为了可使用8000端口,须要先修改防火墙设置)

$ uwsgi --http :8000 --module mysite.wsgi  # 在项目的根目录运行该命令(与运行python manage.py的目录相同),参考"图1"中的目录结构

可是在与nginx联合使用时,端口号由nginx中的配置决定,在uwsgi中就不用配置端口号了(因为nginx与uwsgi之间经过socket通讯,因此直接访问该端口号就能够访问整个django程序)。 

下面是一个配置文件的例子,配置完成后能够在6001端口访问django程序,nginx与uwsgi之间经过"/run/uwsgi/metDNA.sock"进行通讯。

复制代码
server {
    listen                  6001;
    server_name             localhost;  # 这里能够根据实际状况填写域名或localhost
    charset                 utf-8;
    client_max_body_size    50M;

    location / {
        include     uwsgi_params;
        # include     conf.d/corsheaders.conf;
        uwsgi_pass  unix:///run/uwsgi/metDNA.sock;
    }

    # Django media
    location /media  {  # 设置www.ourlab.cn/media的具体路径,这里是django项目配置文件中的`MEDIA_ROOT`的位置
        # your Django project's media files - amend as required
        alias /mnt/data/metdna-upload;
    }

    location /static {  # django项目的静态文件夹位置,即`STATIC_ROOT`的位置
        # your Django project's static files - amend as required
                # first project's static files path
        alias /mnt/data/www/metDNA/metDNA/static/static_root;
    }
}
复制代码

 

更多详情,能够参考:https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html 

uwsig的配置:

  • 具体配置,能够参考这里
  • 由于在配置文件中设置了touch-reload参数,因此更新django代码后,可使用 touch /path/to/wsgi.py 加载更新,而不用重启整个django项目;
  • 使用uwsgi的emperor模式:/usr/bin/uwsgi --emperor /etc/uwsgi/sites,sites文件夹中放的是uwsgi的配置文件mysite.ini(能够放多个django项目相关的配置文件)。该模式始终处于运行状态,若是要中止该django项目,能够重命名sites文件夹下对应的配置文件;

Instances under the control of the emperor should never dies.
If you want to fully stop an instance, simply remove/rename/move the instance config file in a way that the emperor rule will never match.

 

 

nginx的配置


因为一开始不熟悉,所以nginx的配置花了很长时间。其中的关键点是:不一样的server之间是没法共用端口号(port)的,所以若是要使用同一个端口号,例如80端口,那么全部的路由都要配置在一个server中。

  • 配置文件位置:/etc/nginx/ ;
  • 能够将自定义的配置文件放在目录 /etc/nginx/conf.d/,因为在主配置文件 /etc/nginx/nginx.conf 中包含有 include /etc/nginx/conf.d/*.conf; 这条语句,因此该目录下全部的 .conf 文件都会被加载;
  • 自定义的配置文件,能够参考这里nginx.conf,主要是指定端口号和server name(网站域名);

值得注意的是,上面配置文件中的sock文件,例如unix:/run/uwsgi/lipidCCS.sock,nginx的用户和uwsgi的用户须要同时对其进行读写操做,所以都须要相应的权限。靠近前端用户的nginx和靠近后端django程序的uwsgi就是经过这个sock文件进行通讯的。

 

一些命令:

# 重启服务:

$ sudo systemctl restart nginx.service

 

 

其余


进程管理:进程管理的工具也有不少,uWSGI中的Emperor mode与进程管理工具具备类似的功能,二者彷佛没法共用。我选择的是Supervisor。

Supervisor ( http://supervisord.org) 是一个用 Python 写的进程管理工具,能够很方便的用来启动、重启、关闭进程(不只仅是 Python 进程)。除了对单个进程的控制,还能够同时启动、关闭多个进程,好比很不幸的服务器出问题致使全部应用程序都被杀死,此时能够用 supervisor 同时启动全部应用程序而不是一个一个地敲命令启动。

uwsgi程序中的Emperor mode,会与Supervisor相互影响;Emperor mode的做用与Supervisor差很少,但本身感受Supervisor更好用一些

 
php文件:php的运行须要安装php-fpm

 

 

重大修订:

第一次修订于2017年12月20日,补充了uwsgi相关配置的说明,对配置文件添加了注释;

第二次修订于2018年12月27日,勘误以及修复连接(这是每一年这个时间都要写网站的节奏啊!); 

 

参考:

https://zh.wikipedia.org/wiki/%E7%B6%B2%E9%A0%81%E4%BC%BA%E6%9C%8D%E5%99%A8

https://zh.wikipedia.org/wiki/Berkeley%E5%A5%97%E6%8E%A5%E5%AD%97

https://zh.wikipedia.org/wiki/Web%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%BD%91%E5%85%B3%E6%8E%A5%E5%8F%A3

http://djangobook.py3k.cn/2.0/

http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html

https://www.quora.com/What-are-the-differences-between-nginx-and-gunicorn # 这里讲了为何要使用nginx和gunicorn(做用同uWSGI)

http://data-eater.com/python-worker/

http://www.shellwjl.com/2016/03/07/ali_flask_wsgi_Nginx/

相关文章
相关标签/搜索