开发者社区> 问答> 正文

路由与视图 400 请求报错 

Django: 路由与视图 简介 Django与WSGI 创建WSGI应用对象 编写视图函数 定义路由表 对接WSGI服务器

简介

Django框架是美国World Company(世界公司?NB)的工程师Adrian Holovaty和Simon Willison在开发其公司运行的新闻网站(LJWorld.com、Lawrence.com、KUsports.com ) 过程中,逐渐完善丰富而成,2005年开源,是迄今为止Python界名气最大的Web框架。

Django这个词来自吉普赛语,D不发音,中文通常翻为姜戈,不过也有人相当搞笑的称为强哥。 官方发音点这里:

Django框架取名于20世纪三十年代法国著名的爵士吉他手 Django Reinhardt —— 迄今为止最伟大的吉他手之一,尽管他的左手只有三个指头:

Django-Reinhardt

稳定性:Django框架相当抗造,已经被Disqus, Instagram, Pinterest, Mozilla等机构广泛采用,官方 说法是基于Django的站,可以支持每秒5万次点击访问。

产品定位:Django框架的定位是支持大中型动态网站的开发,提供了完备的扩展库和工具集。不过 整个框架分解的比较清晰,如果你愿意抛开Django的工具,深入到各个组件,会发现Django对各种 规模的应用,都能相当不错的支持。

Django与WSGI

根据Python的惯例,Django不是一个完整的Web后端框架,它只负责开发WSGI应用程序 ,在生产环境中Django应用应当与一个WSGI服务器配套,由WSGI服务器负责网络通讯部分。

WSGI,全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义的Web服务器和Web应用程序之间的一种简单而通用的接口。

wsgi2.jpg

WSGI将Web服务分成两个部分:服务器和应用程序。WGSI服务器只负责与网络相关的两件事:接收浏览器的 HTTP请求、向浏览器发送HTTP应答;而对HTTP请求的具体处理逻辑,则通过调用WSGI应用程序进行。

实现一个WSGI应用,只需要满足3个要求:

是可调用的,比如是一个函数,或者是一个可调用类(具有call方法)的实例 WSGI应用应当返回一个可迭代(iterable)的值,比如字符串列表 WSGI应用在返回之前,应当调用WSGI服务器传入的start_response函数发送状态码和HTTP报文头 最小WSGI应用

一种最简单的满足WSGI规约的应用程序需要实现一个指定形式的函数:

from wsgiref.simple_server import make_server def wsgi_app(environ,start_response): start_response('200 OK',[('Context-Type','text/plain')]) return 'such a tiny wsgi app!' httpd = make_server('0.0.0.0',80,wsgi_app) httpd.serve_forever()

environ是一个包含全部HTTP请求信息的字典/Dict,由WSGI服务器解包HTTP请求生成。

创建WSGI应用对象

Django框架对一个WSGI应用的结构进行了分解,有些部件由框架完成,有些部分需要 开发者实现。因此,开发一个基于Django框架的Web应用,事实上就是填充Django框架 所约定的需要由开发者完成的部件。

根据Django约定,一个WSGI应用里最核心的部件有两个:路由表和视图。Django框架 的核心功能就是路由:根据HTTP请求中的URL,查找路由表,将HTTP请求分发到 不同的视图去处理:

hello.jpg

需要指出的是,在Django框架中,由于应用(application)有特定的含义,后续我们 将使用Django项目来表示Django框架中的WSGI应用对象。

创建WSGI应用对象很简单,这通过调用get_wsgi_application()函数来完成。 这个对象用来与WSGI服务器对接:

from django.core.wsgi import get_wsgi_application
wsgi_app = get_wsgi_application()

全局配置对象

不过有一点需要指出,Django框架严重依赖于一个全局配置对象settings来定制 其行为,因此,我们需要在创建WSGI应用对象之前,首先使用默认值初始化这个全局 配置对象:

from django.conf import settings
settings.configure()

在示例代码中你看到,我们设置了其DEBUG 属性为True,这将使Django框架运行在调试状态,输出调试信息。

编写视图函数

DJango中的视图就是一个标准的Python函数,不过由于Django框架要调用 这个函数,因此,作为视图的函数有两个约定需要满足:

view.jpg

输入 :第一个参数是一个HttpRequest对象,这是Django框架对一个HTTP请求 的完整封装,视图函数从这个对象中提取请求中的信息

输出 :返回值应当是一个HttpResponse对象,Django框架将基于这个返回 的对象完成对WSGI服务器的响应

一个简单的视图函数看起来就是这样:

def v_index(req): return HttpResponse('Hello,World!')

视图函数通常是由框架发起调用的,我们不需要直接调用视图函数。不过这并不是被禁止 的,有时候(比如自动测试)还有用处。模仿框架构造一个HttpRequest对象,传给视图 函数就行了:

req = HttpRequest() print v_index(req)

定义路由表

Django框架根据HTTP请求的URL来找到对应的视图函数,很自然的,路由表 使用一个列表对象,其中每一项记录一种URL模式与一个视图函数的对应关系:

urlpatterns = [
    url(r'^$',v_index),
    url(r'^about/$',v_about),
]

url()函数用来生成一个路由项,第一个参数是一个正则表达式,用来匹配 HTTP请求的URL,前缀r用来防止正则字符串被转义;第二个参数就是我们定义 的视图函数。

如果你对正则表达式很熟悉,可能会有一点疑问,为什么上面的正则表达式,都 不包含前面那个/?比如,如果用户请求的URL是/about/,那么我们的正则表达 式应当写成^/about/$才对?

嗯,是这样,简单地说,是Django框架在使用你定义的路由表之前,已经吃掉了 那个前缀的/...先这样吧,回头再细说这一点。

注册路由表

在一个有点规模的应用中,可能会存在多个开发组,每个开发组维护单独的一张路由表。 因此,在Django框架中,需要告诉Django框架使用那个路由表作为根路由表。

使用全局配置对象的ROOT_URLCONF属性来注册根路由表,应当为这个属性指定一个 具有urlpatterns变量的模块名,Django将动态导入这个模块并使用其urlpatterns 变量的值作为路由表。

因此,通常情况下,总应该将路由表变量命名为urlpatterns。

对接WSGI服务器

严格来讲,到上一节课为止,一个Django项目就开发完了,剩下的事情就是 部署到生产环境中去了。

deploy.jpg

在生产环境中,你可以对接生产级的WSGI服务器,比如:Apache + mod_wsgi, Gunicorn或者wWSGI。不过我们还是先跳过这个环节,开发阶段,先找个简单 的WSGI服务器跑起来!

使用Python内置的简单WSGI服务器,引入、创建服务器、运行即可:

from wsgiref.simple_server import make_server
httpd = make_server('0.0.0.0',80,wsgi_app) httpd.serve_forever()

更多内容如URL分发、URL反向解析、视图函数、请求与响应、中间件等以及本文练习请参考: http://www.hubwiz.com/course/562efe441bc20c980538e801/

展开
收起
kun坤 2020-05-30 15:21:09 651 0
1 条回答
写回答
取消 提交回答
  • 2020-05-30 15:21:19
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载