全网第一篇系列讲述Django线上项目实战的文章。前端
上一篇咱们主要完成了Gua的API很简单的GET操做,那么这一节,咱们要说这么几个东西:正则表达式
若是你关注了『皮爷撸码』公众号,而且从公众号里面得知了代码的下载地址,下载代码以后,会看到一个config/config.json
文件,别慌,这个是皮爷故意这么写的。目的就是:数据库
不过,为了让你们读懂代码,我会在config/config.json
文件里面对应的key添加一些解释说明的。django
咱们在上一篇文章讨论了RESTful API的设计规范,可是在前一篇文章,咱们的接口只是很简单的:json
http://127.0.0.1:8000/gua?checkNum=111111复制代码
这个不符合咱们的规范啊,咱们的规范,至少应该是长这个样子的:后端
http://127.0.0.1:8000/v1/api/gua?checkNum=111111复制代码
那么,咱们今天就来实现这样的接口。api
首先,仍是须要来修改咱们的urls.py
文件,将以前的:bash
from apps.Gua.views import GuaViewurlpatterns = [ path('admin/', admin.site.urls), path('gua', GuaView.as_view()),]复制代码
改为服务器
from django.urls import path,includeimport apps.Guaurlpatterns = [ path('admin/', admin.site.urls), path('v1/api/gua', include('apps.Gua.urls')),]复制代码
这里看到,有一个include()
的东西,显然,这里的代码的意思就是,咱们须要在apps/Gua/
目录下面,也建立一个urls.py
文件,咱们建立好,须要在这里面添加如下代码:微信
from django.urls import pathfrom .views import GuaViewurlpatterns = [ path('', GuaView.as_view()) ]复制代码
你看,这里咱们是否是把上一节课的URL给拆成了两个部分来解析?放到两个文件里面作处理。
可是,这里写的这个:
path('', GuaView.as_view())复制代码
实际对应的URL是:
http://127.0.0.1:8000/v1/api/gua复制代码
咱们其实仍是须要后面的checkNum
的,可是,为了符合RESTful API的规范:若是要访问单个资源,请将资源ID也放入到URL中,那么,这个正确的URL就应该是:
http://127.0.0.1:8000/v1/api/gua/111111复制代码
想要实现这样,不难啊,只须要将以前的那个path
改为:
path('/<str:check_num>', GuaView.as_view())复制代码
同时,咱们的GuaView
里面的get()
方法,也得作一些修改,将check_num
做为参数传进去:
def get(self, request, check_num): #下面的逻辑代码省略,只须要注意第三个参数check_num就能够复制代码
好了,这个部分就匹配成功了。其实合起来,咱们是经过:
path('v1/api/gua/<str:check_num>', GuaView.as_view())复制代码
来匹配URL:
http://127.0.0.1:8000/v1/api/gua/111111复制代码
只不过为了灵活性和扩展性,咱们拆开来了。
接着,确定会有小伙伴问<str:check_num>
这是个啥?
其实,这个是Django的路由机制。格式就是:
<类型:变量名>复制代码
转换格式类型 | 说明 |
---|---|
str | 匹配除分隔符(/)外的非空字符,默认类型等价于 |
int | 匹配0和正整数 |
slug | 匹配字母、数字、横杠、下划线组成的字符串,str的子集 |
uuid | 匹配格式化的UUID,如075194d3-6885-417e-a8a8-6c931e272f00 |
path | 匹配任何非空字符串,包括路径分隔符,是全集 |
一样,URL的匹配还支持正则表达式。
之后若是想要扩展本身的API的话,别忘了使用RESTful 规范。
上一篇咱们的数据返回,是在数据库里面拿到数据,通过了一层序列化,把数据转换成Json格式,而后直接返回的,其实,在RESTful规范里面,这样作有些不妥,全部的数据,都应该放到data
里面,这里咱们就来简单实现一下这个。
来到Gua/views.py
文件里面,把咱们的GuaView
的get()
方法作一些调整就好。皮爷这里仅仅只是作了简单的修改,其实应该考虑到各类状况,各类错误的处理,不一样错误还应该有不一样的错误代码等等。咱们目前就先简单来作一下:
def get(self, request, check_num): response = {'code': 200} result = Gua.objects.filter(gua_serial=check_num).first() if result is None: response['code'] = '100090' response['msg'] = 'search_failed' return Response(data=response, status=200) response['msg'] = 'success' serializer = GuaSerializer(result) response['data'] = serializer.data return Response(data=response, status=200)复制代码
能够看到,在最后的Response()
里面的data
, 咱们传入了一个dict()
类型的数据,这个数据是咱们本身封装好的。最后的返回结果以下图:
能够看到,搜搜结果数据是在data
里面放着。
其实,对于一个后端程序来讲,POST的方法和GET方法都是很常见的,咱们以前,在GuaView
里面编写的get()
方法,其实就是对应的GET method。对于一些操做,咱们须要将数据存储到服务器上,这个时候,咱们就要使用POST方法了。那么,实现POST方法其实也很简单,只须要编写对应的post()
方法就能够了。
常规来讲,POST的请求,若是请求成功,服务器须要将存储的数据返回到前端,以表示请求成功。这里,我就来列举代码中的一个post()
方法,来给你们说一下写post有哪些注意的地方:
# 这里的model之类的就都先省略了,直接来讲方法 def post(self, request): app_version = request.data.get('appVersion') checkNum = request.data.get('checkNum') gender = request.data.get('gender', "") fromPage = request.data.get('fromPage') gua_r = GuaRModel() gua_r.appVersion = app_version gua_r.checkNum = checkNum gua_r.gender = gender gua_r.fromPage = fromPage year = str(datetime.datetime.now().year) month = str(datetime.datetime.now().month).zfill(2) day = str(datetime.datetime.now().day).zfill(2) gua_r.dayTime = "{}{}{}".format(year, month, day) gua_r.guaName = Gua.objects.filter(gua_serial=checkNum).first().gua_title result = gua_r.save() response = {} if result is None: response['code'] = '100093' response['msg'] = 'Report failed' return Response(datetime=response) response['code'] = '200' response['msg'] = 'success' serializer = GuaReportSerializer(gua_r) response['data'] = serializer.data return Response(data=response)复制代码
能够看到,这个方法首先是来处理POST请求传过来的那些参数的值。而后,建立一个咱们须要存储的类,再将这些数值赋给它,最后调用一个model.save()
方法就好,最后在把刚才的数据序列化,返回到前端就好。是否是很简单啊?固然,这里只是最简单的POST操做,POST还有不少复杂的操做,之后慢慢给你们道来。
Restframework的分页有好几种实现方式:
settings.py
中直接设置;PageNumberPagination
实现分页;LimitOffsetPagination
实现分页;CursorPagination
实现分页。这里,皮爷使用的是自定义PageNumberPagination
来实现的分页。
首先,咱们先来收一下如何在settings.py
里面,只须要直接加入如下配置就能够:
# rest framework系统自带的分页REST_FRAMEWORK = { # 分页 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', # LimitOffsetPagination 分页风格 'PAGE_SIZE': 30, # 每页多少条记录}复制代码
接下来,咱们说一下如何自定义PageNumberPagination
来实现的分页。
咱们在Gua/views.py
里面,首先写一个class,继承PageNumberPagination
:
from rest_framework.pagination import PageNumberPaginationclass GuaRPagination(PageNumberPagination): page_size = 30 # 表示每页的默认显示数量 page_size_query_param = 'page_size' # 表示url中每页数量参数 page_query_param = 'page' # 表示url中的页码参数 max_page_size = 100 # 表示每页最大显示数量,作限制使用,避免忽然大量的查询数据,数据库崩溃复制代码
而后,咱们只须要在须要分页的地方,这么写就能够:
def get(self, request,*args,**kwargs): response = {'code': 200} result = GuaRModel.objects.all() response['msg'] = 'success' response['size'] = len(result) # 如下几行代码是关键 pg = GuaRPagination() page_role = pg.paginate_queryset(queryset=result, request=request, view=self) serializer = GuaReportSerializer(page_role, many=True) response['data'] = serializer.data return Response(data=response, status=200)复制代码
由于咱们在GuaRPagination
里面定义了请求URL里面能够携带分页的参数:page
和page_size
,分别表示请求第几页内容
和当前页面最大显示条数
。因此,咱们的请求URL就能够变成这个样子:
# 表示请求第三页,每页最大显示10条数据http://127.0.0.1:8000/v1/api/gua/list?page=3&page_size=10复制代码
好比测试,咱们若是请求如下接口:
http://127.0.0.1:8000/v1/api/gua/list?page=3&page_size=6复制代码
那么应该表示的是第三页,而且显示的是六条数据:
看到,是否是这样?哈哈哈哈啊。
好了,今天说的内容不少,接口还有不少内容,好比权限管理啊等等,这些我往后都会说道。皮爷只有一个宗旨:就是要让你经过个人这个系列的文章,可以开发出来一套完整的系统。
这些全部代码,我都会上传到GitHub上,获取方式就是请关注微信公众号『皮爷撸码』,而后回复『网站代码』便可得到连接地址。
好了,系列文章今天这一章节就先说到这里,正好立刻就要双11了,又到了一年一度买服务器的时候了。照目前的趋势,皮爷今年确定又会购买服务器了,服务器是真的不嫌多啊,一台服务器能够写网站,两台服务器就能够玩 RPC,三台能够搞集群。。。
下面这个连接你们能够在双十一的时候在阿里云享受优惠,注意,每一年就此一次,错过了可就要等一年的哦:
https://www.aliyun.com/1111/2019/group-buying-share?ptCode=59102A206508DC8B402167FFD766D480647C88CF896EF535&userCode=nrkmbo9q&share_source=copy_link
喜欢的同窗,能够把皮爷的文章分享出来,让跟多的人一块儿来学习。这个系列教程的文章,皮爷都会讲源代码放到 GitHub 上,想要获取代码的同窗,请关注微信公众号『皮爷撸码』,而后回复『网站代码』便可得到连接地址。这里有更多更好玩的东西,等你一块儿来学习提升。