Djang o知识点整理
web 框架?
框架,即framework
,特指为解决⼀个开放性问题⽽设计的具有⼀定约束性的⽀撑结构,使⽤框架可以帮你快速开发特定的系统,简单地说,就是你⽤别⼈搭建好的舞台来做表演。*浏览器发送⼀个HTTP 请求;
*服务器收到请求,⽣成⼀个HTML ⽂档(待补充;是否是全部类型的访问都需要⽣成⽂档);
*服务器把HTML ⽂档作为HTTP 响应的Body 发送给浏览器;
*浏览器收到HTTP 响应,从HTTP Body 取出HTML ⽂档并解析显⽰
对于所有的Web 应⽤,本质上其实就是⼀个socket 服务端,⽤户的浏览器其实就是⼀个socket 客户端。
# -*- coding: utf-8 -*-
# @Date : 2016/11/24
# @Author : Jesson
import  socket
def  handle_request (client ):
buf = client .recv (1024)
client .send ("HTTP/1.1 200 OK\r\n\r\n".encode ("utf8"))
client .send ("<h1 style='color:#1b7665'>Hello, Jesson</h1>".encode ("utf8"))
def  main ():
sock = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
sock .bind (('localhost',8001))
sock .listen (5)
whileTrue :
connection , address = sock .accept ()
handle_request (connection )
connection .close ()
if  __name__ =='__main__':
main ()</pre >
地址栏输⼊访问请求:
最简单的Web 应⽤就是先把HTML ⽤⽂件保存好,⽤⼀个现成的HTTP 服务器软件,接收⽤户请求,从⽂件中读取HTML ,返回。
如果要动态⽣成HTML ,就需要把上述步骤⾃⼰来实现。不过,接受HTTP 请求、解析HTTP 请求、发送HTTP 响应都是苦⼒活,如果我们⾃⼰来写这些底层代码,还没开始写动态HTML 呢,就得花个把⽉去读HTTP 规范。
正确的做法是底层代码由专门的服务器软件实现,我们⽤Python 专注于⽣成HTML ⽂档。因为我们不希望接触到TCP 连接、HTTP 原始请求和响应格式,所以,需要⼀个统⼀的接⼝,让我们专⼼⽤Python 编写Web 业务。
这个接⼝就是WSGI :Web Server Gateway Interface 。
WSGI ,全称 Web Server Gateway Interface ,或者 Python Web Server Gateway Interface ,是为 Py
thon 语⾔定义的 Web 服务器和 Web 应⽤程序或框架之间的⼀种简单⽽通⽤的接⼝。⾃从 WSGI 被开发出来以后,许多其它语⾔中也出现了类似接⼝。
WSGI 是作为 Web 服务器与 Web 应⽤程序或应⽤框架之间的⼀种低级别的,以提升可移植 Web 应⽤开发的共同点。WSGI 是基于现存的 CGI 标准⽽设计的。
很多框架都⾃带了 WSGI server ,⽐如 Flask ,webpy ,Django 、CherryPy 等等。当然性能都不好,⾃带的 web server 更多的是测试⽤途,发布时则使⽤⽣产环境的 WSGI server 或者是联合 nginx 做 uwsgi 。
web 应⽤ 访问请求流程
socket 实例
WSGI 简单介绍
通俗来讲,WSGI 就像是⼀座桥梁,⼀边连着web
服务器,另⼀边连着⽤户的应⽤。但是呢,这个桥的功能很弱,有时候还需要别的桥来帮忙才能进⾏处理。
WSGI 有两⽅:“服务器”或“⽹关”⼀⽅,以及“应⽤程序”或“应⽤框架”⼀⽅。服务⽅调⽤应⽤⽅,提供环境信息,以及⼀个回调函数(提供给应⽤程序⽤来将消息头传递给服务器⽅),并接收Web 内容作为返回值。
所谓的 WSGI 中间件同时实现了API 的两⽅,因此可以在WSGI 服务和WSGI 应⽤之间起调解作⽤:从WSGI 服务器的⾓度来说,中间件扮演应⽤程序,⽽从应⽤程序的⾓度来说,中间件扮演服务器。“中间件”组件可以执⾏以下功能:
重写环境变量后,根据⽬标URL ,将请求消息路由到不同的应⽤对象。
允许在⼀个进程中同时运⾏多个应⽤程序或应⽤框架。
负载均衡和远程处理,通过在⽹络上转发请求和响应消息。
进⾏内容后处理,例如应⽤XSLT 样式表。
WSGI 的设计确实参考了 Java 的 servlet 。 有这么⼀段话:
By contrast, although Java has just as many web application frameworks available, Java's "servlet" API makes it possible for applications written with any Java web
application framework to run in any web server that supports the servlet API.
另外,需要提及的⼀点是:其它基于python 的web 框架,如tornado 、flask 、webpy 都是在这个范围内进⾏增删裁剪的。例如tornado ⽤的是⾃⼰的异步⾮阻塞“wsgi”,flask 则只提供了最精简和基本的框架。Django 则是直接使⽤了WSGI ,并实现了⼤部分功能。
# -*- coding: utf-8 -*-
from  wsgiref .simple_server import  make_server
def  application (environ , start_response ):
start_response ('200 OK',[('Content-Type','text/html')])
return [b '<h1 >Hello, web!</h1>']
#''中间为空,表⽰的是本地地址
httpd = make_server ('',8080, application )
print ('Serving HTTP on ')
# 开始监听HTTP 请求:
httpd .serve_forever ()</pre >
整个application ()函数本⾝没有涉及到任何解析HTTP 的部分,也就是说,底层代码不需要我们⾃⼰编写,
我们只负责在更⾼层次上考虑如何响应请求就可以了。
application ()函数必须由WSGI 服务器来调⽤。有很多符合WSGI 规范的服务器,我们可以挑选⼀个来⽤。
Python 内置了⼀个WSGI 服务器,这个模块叫wsgiref
application ()函数就是符合WSGI 标准的⼀个HTTP 处理函数,它接收两个参数://environ :⼀个包含所有HTTP 请求信息的dict 对象; //start_response :⼀个发送HTTP 响应的函数。在application ()函数中,调⽤:
start_response ('200 OK',[('Content-Type','text/html')])
就发送了HTTP 响应的Header ,注意Header 只能发送⼀次,也就是只能调⽤⼀次start_response ()函数。
start_response ()函数接收两个参数,⼀个是HTTP 响应码,⼀个是⼀组list 表⽰的HTTP Header ,每
个Header ⽤⼀个包含两个str 的tuple 表⽰。
通常情况下,都应该把Content -Type 头发送给浏览器。其他很多常⽤的HTTP Header 也应该发送。
然后,函数的返回值b '<h1>Hello, web!</h1>'将作为HTTP 响应的Body 发送给浏览器。
有了WSGI ,我们关⼼的就是如何从environ 这个dict 对象拿到HTTP 请求信息,然后构造HTML ,
通过start_response ()发送Header ,最后返回Body 。</pre >
from  wsgiref .simple_server import  make_server
def  f1():
f1=open ("jd_index1.html","rb")
ad ()
return [data1]
def  f2():
WSGI 的作⽤
WSGI 实例⼀
WSGI 实例⼆
f2=open("tb_index.html","rb")
ad()
return[data2]
def application(environ, start_response):
print(environ['PATH_INFO'])
path=environ['PATH_INFO']
start_response('200 OK',[('Content-Type','text/html')])
# 如果URL路径为京东,执⾏函数1,返回京东主页
if path=="/jingdong":
return f1()
# 如果URL路径为淘宝,执⾏函数2,返回淘宝主页
elif path=="/taobao":
return f2()
else:
return["<h1>404</h1>".encode("utf8")]
httpd = make_server('',8810, application)
print('Serving HTTP on ')
# 开始监听HTTP请求:
httpd.serve_forever()
打开浏览器访问相应的路径
这⾥我们WSGI每次修改完数据后,都需要重新启动该服务。WSGI实例3 打印当前时间
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2016/11/24
# @Author  : Jesson
import time
from wsgiref.simple_server import make_server
def f1(req):
print(req)
print(req["QUERY_STRING"])
f1=open("jd_index1.html","rb")
ad()
return[data1]
def f2(req):
f2=open("tb_index.html","rb")
ad()
return[data2]
def f3(req):#模版以及数据库
f3=open("current_time.html","rb")
ad()
times=time.strftime("%Y-%m-%d %X", time.localtime()) # 在前端相应的页⾯设置⾃定义模版语⾔'! !'
data3=str(data3,"utf8").replace("!time!",str(times))
de("utf8")]
def routers():
urlpatterns =(
('/jingdong',f1),
('/taobao',f2),
("/cur_time",f3)
)
return urlpatterns
def application(environ, start_response):
print(environ['PATH_INFO'])
path=environ['PATH_INFO']
start_response('200 OK',[('Content-Type','text/html')])
urlpatterns = routers()
func =None
for item in urlpatterns:
if item[0]== path:
func = item[1]
break
if func:
web前端的基本框架return func(environ)
else:
return["<h1>404</h1>".encode("utf8")]
httpd = make_server ('',8828, application )
print ('Serving HTTP on ')
# 开始监听HTTP 请求:
httpd .serve_forever ()</pre >
其实,上边⼏个实例就相当于⼀个简单的web 框架。
MVC 百度百科:全名Model View Controller ,是模型(model)-视图(view)-控制器(controller)的缩写,⼀种软件设计典范,⽤⼀种业务逻辑、数据、界⾯显⽰分离的⽅法组织代码,将业务逻辑聚集到⼀个部件⾥⾯,在改进和个性化定制界⾯及⽤户交互的同时,不需要重新编写业务逻辑。
通俗解释:⼀种⽂件的组织和管理形式!不要被缩写吓到了,这其实就是把不同类型的⽂件放到不同的⽬录下的⼀种⽅法,然后取了个⾼⼤上的名字。当然,它带来的好处有很多,⽐如前后端分离,松耦合等等,就不详细说明了。       
模型(model):定义数据库相关的内容,⼀般放在models.py ⽂件中。
视图(view):定义HTML 等静态⽹页⽂件相关,也就是那些html 、css 、js 等前端的东西。
控制器(controller):定义业务逻辑相关,就是你的主要代码。 
MTV: 有些WEB 框架觉得MVC 的字⾯意思很别扭,就给它改了⼀下。view 不再是HTML 相关,⽽是主业务逻辑了,相当于控制器。html 被放在Templates 中,称作模板,于是MVC 就变成了MTV 。这其实就是⼀个⽂字游戏,和MVC 本质上是⼀样的,换了个名字和叫法⽽已,换汤不换药。
在web 开发的项⽬⽂件中,相关⽬录分开存放,必须要有机制将他们在内⾥进⾏耦合。在Django 中,urls 、orm 、static 、settings 等起着重要的作⽤。
⼀个典型的业务流程是如下图所⽰:
那么我们学Django 学的是什么?1. ⽬录结构规范2. urls 路由⽅式3. settings 配置4. ORM 操作5. 模板渲染6. 其它
# Django
# 安装: pip3 install django
添加环境变量
#1  创建project ⼯程
django -admin startproject mysite
---mysite
---settings .py
---url .py
---wsgi .py
---manage .py (启动⽂件)
#2  创建APP 应⽤
python mannage .py startapp  app01
#3  settings 配置
TEMPLATES
STATICFILES_DIRS =(
MVC 和MTV 设计模式
MVC/MTV 介绍
Django 的MTV 模型组织
Django ⼯作流程和命令⾏⼯具
基本流程
os.path.join(BASE_DIR,"statics_⾃定义"),
)
STATIC_URL ='/static/'
# 我们只能⽤ STATIC_URL,但STATIC_URL会按着你的STATICFILES_DIRS去
<script src="/statics_⾃定义/jquery-3.1.1.js"></script>
------这么写可以实现,但是不规范-----不能直接⽤,必须⽤STATIC_URL ='/static/'
<script src="/static/jquery-3.1.1.js"></script>
采⽤第⼆种⽅式,后端的更改不会影响前端的引⼊,避免造成前端⼤量修改。
#4  根据需求设计代码
url.py
view.py
#5  使⽤模版
render(req,"index.html")
#6  启动项⽬
python manage.py runserver  127.0.0.1:8090
#7  连接数据库,操作数据
model.py
django的命令⾏⼯具
django-admin.py 是Django的⼀个⽤于管理任务的命令⾏⼯具,manage.py是对django-admin.py的简单包装,每⼀个Django Project⾥都会有⼀个mannage.py。
创建⼀个django⼯程 : django-admin.py startproject mysite当前⽬录下会⽣成mysite的⼯程,⽬录结构如下:
manage.py ----- Django项⽬⾥⾯的⼯具,通过它可以调⽤django shell和数据库等。
settings.py ---- 包含了项⽬的默认设置,包括数据库信息,调试标志以及其他⼀些⼯作的变量。
urls.py ----- 负责把URL模式映射到应⽤程序。
在mysite⽬录下创建blog应⽤: python manage.py startapp blog
启动django项⽬:python manage.py runserver 8080这样我们的django就启动起来了!当我们访问:
⽣成同步数据库的脚本⽂件:python manage.py makemigrations 同步数据库: python manage.py migrate
注意:
在开发过程中,数据库同步误操作之后,难免会遇到后⾯不能同步成功的情况,解决这个问题的⼀个简单粗暴⽅法是把migrations⽬录下的脚本(除init.py之外)全部删掉,再把数据库删掉之后创建⼀个新的数据库,数据库同步操作再重新做⼀遍。
当我们访问
所以我们需要为进⼊这个项⽬的后台创建超级管理员:python manage.py createsuperuser 终端执⾏上述命令,设置好⽤户名和密码后便可登录啦!设置⽤户名的时候,邮箱email可以不⽤输⼊,密码有复杂度校验,设置的复杂点。另外,还会提⽰你,密码会明⽂显⽰。
Warning: Password input may be echoed.
OK~ 如此优雅的后台界⾯!
清空数据库: python manage.py flush
查询某个命令的详细信息: django-admin.py help startappadmin 是Django ⾃带的⼀个后台数据库管理系统。
启动交互界⾯:python manage.py shell这个命令和直接运⾏ python 进⼊ shell 的区别是:你可以在这个 shell ⾥⾯调⽤当前项⽬的 models.py 中的 API,对于操作数据,还有⼀些⼩测试⾮常⽅便。
>#思考题补充:
(1) 如何更改正在运⾏的开发服务器端⼝
#进⼊django命令⾏,执⾏:
python manage.py runserver 加上新的端⼝号8080
Django URL (路由系统)
URL配置(URLconf)就像Django 所⽀撑⽹站的⽬录。
它的本质是URL模式以及要为该URL模式调⽤的视图函数之间的映射表;你就是以这种⽅式告诉Django,对于这个URL调⽤这段代码,对于那个URL调⽤那段代码。
`urlpatterns =[`
`url(正则表达式, views视图函数,参数,别名),`
`]`
参数说明:
⼀个正则表达式字符串
⼀个可调⽤对象,通常为⼀个视图函数或⼀个指定视图函数路径的字符串
可选的要传递给视图函数的默认参数(字典形式)
⼀个可选的name参数
URL conf实例
f.urls import url
ib import admin
from app01 import views

发表评论