开发者学堂课程【Python Web 框架 Django 快速入门:Django 用户接口设计之路由配置、视图函数】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/604/detail/8812
Django 用户接口设计之路由配置、视图函数
内容简介:
一、如何来做一套系统?
二、现在的做法
三、用户注册接口设计
四、路由配置
五、reg 分配的方式讲解
六、视图函数
七、测试 JSON 数据
八、JSON 数据处理
九、错误处理
一、如何来做一套系统?
前面是一个浏览器,中、5间一分隔,后面解决静态问题,动态的写一个 python,对于某一种 URL 开头,则去找 python。对于某一些 URL 可以用 PHP 写,还有一些 URL 可以使用 JAVA 来写。解决好动态和静态问题,通过前端代理根据URL不同选择不同的服务器。对于浏览器来讲,它并不知道后面有多少服务,有时候甚至会出现 502服务器操作错误。如果再添加一个 python 服务,每一个 python 只完成一个子功能,URL 可以直接跟新建的 python 连接,两个 python 之间也可以互相连接,通过 HTTP 报出 API 。现在的问题是现在访问一个静态的服务器,这个静态服务器是用 relax 写出来的,同时它可以做一些返回。
如果不知道后面还有个 Python 该怎么办呢?
可以给一些基于 Http 的 API,可以设计一下
Http:// 内部 IP/pass to/? 还可以采用 post 方法或者 Got 方法。
蓝色部分之间可以互相传送数据,上面缺少访问数据库的能力,Gjango 可以访问 DB,Gjango 可以把数据整理好然后返回 Json,n 通过 relax 框架,relax 最后 ban 住 JS ,里面通过访问 AJAX。
可以发现它们的偶合很小,纯粹就是定义的数据,其他都没有了。
以上做到的东西就是前后端分离。
n通过视图提供给客户端。总之,要么把路由交给静态服务器处理,要么把路由交给动态服务器处理。
每一次发起都是 Http 请求, Django 服务器纯粹就是一个提供数据的服务,可以变成内部的一个服务,每一个服务各司其职,以前写东西,经常是在 Django 上面写一个很大很大的系统,现在并不会这样做了,现在都是将其拆开,尽可能多的拆开更多的服务,然后服务之间通过接口调用减少它们之间的偶合,这样代码可以进行复用,系统用子系统服务时直接搬过去就可以了。
同时部署上压力也不大了,以前都是写成很大一个东西,出问题就很容易全部都出错,现在就只是一个服务出错,出错之后就再找一个服务即可。
如果 Django 服务压力很大,就可以多部署几个,化整为零好处还是比较多的。
二、现在的做法
当问 devs 要数据, devs 数据回到 js,回来就是 html ,即动态生成。但是里面有一个按钮,当一摁这个按钮,就是在要数据了,这时候它就会发起一个请求,先请求给 devs,devs 看完之后, 将 AP 开头的转发给 Django,然后由 Django 返回给 API,API 又会返回给 AJAX,就是这样的一个过程。但是对于浏览器端来看的话,它是在一直访问 devs。大多数静态服务器可以进行更多的缓存,动态内容的缓存还以做,但是动态缓存会有很多问题,例如实时性不强。总的来说如果是内部系统用,还是够用了。以上就是大概的架构。
三、用户注册接口设计
接收用户通过 Post 方法提交的注册信息,提交的数据是 JSON 格式数据
检查 email 是否已存在与数据库表中,如果存在返回错误状态码,例如 4xx,如果不存在,将用户提交的数据存入表中
整个过程都采用 A]JAX 异步过程,用户提交 JSON 数据,服务端获取数据后处理,返回 JSON.
URL : /userlreg
METHOD : POST
POST 提交的数据信息是 JSON 的数据格式。如果必须通过 JSON 格式来传,则需要用 JS 进行组织。当拿到 JSON 数据的时候,要进行提取出客户发送的 email,可以去数据库里面查一下,可以看看有没有,如果有就不对了,就要往回抛状态码。不是请求资源不存在而是已经存在了,如果查有此邮箱,则给用户返回 4XX的错误。如果不存在,说明 email 可以作为登录的账户用,就是可以的。对于后端开发,不需要用浏览器,用工具就可以解决。
定义 URL :当用户访问一个 URL ,配上 POST 方法,再配上提交的 JSON,就可以访问定义的这个接口。
四、路由配置
不用模板
From diango .shortcuts import render
Create your views here
from django.http import JsonResponse,HttpRequest, HttpResponse
def reg{request}
print [request," ~~~~~~~~~~~~",
Print[tyEe{requost})
print {request.GET}
Print {requeat.POST}
return JaonResponse{”welcome to magedu”}
from django.conf.urlE import url, includefrom django.contrib import admin
from django.http import HttpResponse,JsonResponsefrom django.template import loader,RequestContext
#模板
from django.shortcuts import render
def index(request):
print (request)
print (type (request) )
#tpl = loader.get_template ( 'index.html " )
#context = RequestContext (request,{ ' content ' : ' www .magedu.com ' })#return HttpResponse (tpl.render (context) )
d = dict (zip ( ' abced' , range ( 1,6) ))
print (d)
return render(request,'index.html ',{ 'd' :d}) # html str { 'a ': 1,'b':2)#return JsonResponse ( { 'user ' : ' hello magedu ' }) # json str
urlpatterns = [
url (r"一admin/ " , admin.site.urls) ,url(r '一index/$ ' , index),
url(r'一$', index) ,
url(r"一user/ ', include{user.urls})
主要POST和URL一定要正确。
{
" password" : "abc",
"name" : "tom" ,
"email" : "tomemagedu. com""
}
MIDDLEWARE [
'django.middleware.security.securityMiddleware ' ,
'django.contrib.sessions.middleware.sessionMiddleware '
'django.middleware.common . CommonMiddleware ' ,
' django.middleware.csrf.CsrfViewMiddleware' ,
'django.contrib.duth .middleware.AuthenticationMiddleware ' 'django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware '
操作主要是打印GET和POST
但是程序里面没有GET,因为走的不是查询字符串。
Django version 1.11,using settings "blog.settings"
Starting development server at
Quit the server with CTRL-BREAK.
[09/jul/2018 14:49:09] "POST /user/reg HTTP/1.1" 200 17
程序产生了多支,因为 ID=1, ID=2 就产生了多支。
如上图为登录表单,是一种传数据的方式,写几个登录框和提交按钮,在表单就提交过来了,
但是现在用的就是比较少了。
现在就是先直接上传一个 JSON ,然后用到下面的数据。
{
" password":"abc",
"name": "tom"
email" :"tom@magedu. com
}
现在请求方式变化了,代码没有变,发送请求。POST 请求的内容一定会放在一个地方的。如果去打印在 REQUEST 前面加一个断点,这个时候是停不下来,所以就是靠打印,这时候还有另一个属性 print (request .body,”~~~~~~~~~”)。
字符串有了,接下来输入 JAON ,输入
print (json. Loads(re0quest.body.decade()),”~~~~~~~~~”),注意看状态码。payload =json. Loads(request。body. Decode(). 要把这三个值拿出来,目前还没考虑数据库问题。这是内部服务相对好,但是可能由于某种原因凑出 JSON,所以可能不太合法,所以转换过程中有可能会出错。
比如说编码问题,有人会因为汉字编码问题在转换过程中会出现各种问题。
实际上还要进行
logging . basicConfig (format=FORMAT, level=logging . INFO) 操作,下面还要加上 logging. info(e)。
真正写项目的时候,日志肯定是要有的,而且都是输出到文件。如果出错,最后应该改成 return HttpResponseBadRequest(). 只要过程里面出任何错误,
几乎都是客户端发起请求出现的错误。通过分析可以知道程序中并没有被提供一个JSON,数据在 body 里面,在 body 里面按照它的要求进行改变和转换,之后JSON 会转换成一种数据结构,这个数据结构在转换过程中可能会出错,有可能在访问想要的 key 没有,因为对方会技术,它可以分析在登录或者注册时的数据包,故意造成障碍。有可能在数据来的时候不符合要求,解析成 JSON 的问题,都是由于用户提交的一些非法数据引起的,说到底是没有找到资源。这个时候不希望是 404,这时候可以发送几个 GET 请求到服务器端。程序中最重要的是email,可以用 get 方法将 email 取出来,但是 get 方法不抛异常,所以本次没有使用 get 方法。
可以输入 email=payload (“email”),要去数据库中看看 email 有没有,是很重要的。
实际上,做外部开发可以不用浏览器,因为主要是看数据,因为在和服务端交互的时候往往都是 url 加 post,get 方法。只要发送一个简单请求,然后使用调试工具就可以了。如果用户发回来的是 HTML ,用这个工具都可以显示。
整体程序如下:
FORMAT="% (asctime)s 8 (threadName)s%(thread)d%(message) s"
logging . basicConfig (format-FORMAT, level=logging . INFO)
from django.http import JsonResponse, HttpRequest, HttpResponse, HttpResponseBadRequest
import json
def reg (request: HttpRequest) :
print (request,” ~~~~~~~~~~~~”)
try:
payload = json. loads (request . body . decode ())
Email=payload[ ' email' ]
return HttpResponse ("welcome to magedu")
except Exception as e:
logging. info(e)
return HttpResponseBadRequest ()
映射可以采用多级的方式,在多级里面,url(r'^reg$',reg) 中的 r'^reg$' 相当于把第一级替换掉了,用的是分配的方式。
五、reg 分配的方式讲解
# /user/reg [matcher. end():] 从 matcher 的对象开始,前面的内容匹配完之后剩下的部分继续做,[matcher. end():] 会生成 newcopy ,是分段的 copy,完成匹配之后就可以指向函数,在函数中接入数据,第一个解决的问题就是怎么样去拿到一个 JSON,可以通过 simplejson,需要去操作一下,输入 pip install simplejson。
为了避免项目中的 urls.py 条目过多,也为了让应用自己管理路由,采用多级路由。
# blog/ur1s. py中
urlpatterns =[
ur1(r'^admin/', admin. site. urls),
url(r'n$',index),
url(r'index/$',index),
url(r'Auser/', include( ' user . urls ))
]
include函数参数写应用.路由模块, 该函数就会动态导入指定的包的模块,从模块里面读取 urlpatterns ,返回三元组。返回三元组后第二个参数就可以用了。
url 函数第二参数如果不是可调用对象,如果是元组或列表,则会从路径中除去已匹配的部分,将剩余部分与应用中的路由模块的 urlpatterns 进行匹配。
#新建 user/urls.py
from django. conf . urls import url
#临时测试用 reg 视图函数
from django . http import HttpRequest, HttpResponse
def reg( request :HttpRequest):
return HttpResponse(b' user.reg')
urlpatterns = [
url(r'^reg$', reg)
浏览器中输入http://127.0.0.1:8000/user/reg测试- -下 ,可以看到响应的数据。下面开始完善视图函数。
六、视图函数
在 user/views.py 中编写视图函数 reg ,路由做响应的调整。
七、测试 JSON 数据
使用 POST 方法,提交的数据类型为 applicatinjson , json 字符串要使用双引号
这个数据是登录和注册用的,由客户端提交
(
"password": "abc",
"nane": "wayne" ,
" 'emal1" :”wayne@magedu. com"
)
八、JSON 数据处理
simplejson 比标准库方便好用,功能强大。
$ pip install sirplejson
浏览器端提交的数据放在了请求对象的 body 中,需要使用 simplejson 解析,解析的方式同 json 模块,但是 simplejson 更方便。
九、错误处理
Django 中有很多异常类,定义在 django.http 下,这些类都继承自 HttpResponse.
# user/views.py中
from django.http import HttpRequest, HttpResponse, HttpRes ponseBadRequest, JsonResponse
import simplejson
def reg(request :HttpRequest):
print( request . POST)
print(request . body)
pay1oad = simplejsor. loads(request. body)
try:
email = payload[' email']
name = payload[' name']
password = payload[ ' password' ]
print(email, name, password)
return JsonResponse({}) #如果正常,返回json数据
except Exception as e: #有任何异常,都返回
return HttpResponseBadRequest() #这里返回实例,这不是异常类