#接口:url连接,通过向链接发送不同的类型请求与参数得到相应的响应数据 #1.在视图书写处理请求的 视图函数 #2.在路由层为视图函数配置 url链接=>产生接口 #3.前台通过ajax,爬虫,工具等对接口发送请求,提交相应的参数获得对应的响应数据 # https://api.map.baidu.com/place/v2/search ‘‘‘ ak: 6E823f587c95f0148c19993539b99295 region: 上海 query: 肯德基 output: json ‘‘‘
#定义接口的规范 # REST:表征性状态转移(Representational State Transfer) #RESTful规范:web数据请求接口设计规范 #学习的目的: #1.如何设计url链接地址 #2.如何设计响应的数据格式 ‘‘‘ 1)通常使用https请求 2)域名:有api关键字出现 -- https://api.baidu.com (可能涉及跨越问题) -- https://baidu.com/api 3)版本:不同版本需要标注 -- https://example.com/api/v1 | -- https://example.com/api/1 -- https://example.com/api/v2 | -- https://example.com/api/2 4)资源:请求的目标数据称之为资源,资源一般都用名词复数表示 -- https://example.com/api/v1/books (之前不规范的案例: /get_books/) 5)操作方式:不从请求链接体现操作方式,从请求方式上决定操作方式 -- get:https://example.com/api/v1/books 获取所有 -- post:https://example.com/api/v1/books 新增一本 -- put:https://example.com/api/v1/book/1 更新id=1的一本 -- patch:https://example.com/api/v1/book/1 更新id=1的一本 -- delete:https://example.com/api/v1/book/1 删除id=1的一本 6)资源过滤:通过接口传递参数来过滤资源 -- https://example.com/api/v1/books?limit=10 限制10条 7)状态码:返回数据要标准状态码,通过在数据中 {"status": 0} -- SUCCESS("0", "查询成功") -- NODATA("1xx", "非正确,无数据,显示基本信息") -- FEAILED("2xx", "查询失败") 8)错误信息:请求失败需要标注错误信息 {"msg": "请求参数不合法"} 9)操作结果:请求操作成功的返回结果 {"results": []} -- get:返回资源列表 | 返回单一资源 -- post:返回单一新增资源 -- put:返回更新的资源 -- patch:返回更新的资源 -- delete:返回空文档 10)子资源返回资源接口:返回的资源如果有子资源,返回子资源的链接地址,如查找书,书的封面图片就可以url表示 ‘‘‘
‘‘‘ 1.url链接设计:采用https方式,有api关键字,有版本需要明确版本,请求链接用名词来表示资源,具体的操作方式采用请求方式来确定 2.url响应数据设计:需要明确状态码、错误信息、成功结果,子资源一般用子资源的接口来标注 ‘‘‘
#路由层 from app import views urlpatterns = [ url(r‘^books/‘, views.books), ] #视图层 from django.http import JsonResponse book_list = [ { ‘id‘: 1, ‘name‘: ‘三国演义‘ }, { ‘id‘: 2, ‘name‘: ‘水浒传‘ } ] def books(request): if request.method == ‘GET‘: ak = request.GET.get(‘ak‘, None) if not ak: return JsonResponse({ ‘status‘: 101, ‘message‘: ‘没有明确ak‘, }, json_dumps_params={‘ensure_ascii‘: False}) return JsonResponse({ ‘status‘: 0, ‘message‘: ‘ok‘, ‘results‘: book_list }, json_dumps_params={‘ensure_ascii‘: False}) if request.method == ‘POST‘: # return HttpResponse(‘post back‘) name = request.POST.get(‘name‘) id = len(book_list) + 1 book = {‘id‘: id, ‘name‘: name} book_list.append(book) return JsonResponse({ ‘status‘: 0, ‘message‘: ‘ok‘, ‘results‘: book }, json_dumps_params={‘ensure_ascii‘: False})
‘‘‘ 1)as_view() --User.as_view()本质拿到view(request,*args,**kwargs)函数对象 2)view(request,*args,**kwargs) --return self.dispatch(request,*args,**kwargs)来完成请求的反射 3)dispatch(request,*args,**kwargs) --完成具体的请求响应的分发 #注:重写dispatch事可以再分发响应时,加入其他逻辑限制 ‘‘‘
#路由层 urlpatterns = [ url(r‘users/‘, views.Users.as_view()) ] #视图层 from django.views import View class Users(View): def dispatch(self, request, *args, **kwargs): pass # 可以对请求加以限制 result = super(Users, self).dispatch(request, *args, **kwargs) pass # 可以对请求再近一步处理 return result def get(self, request, *args, **kwargs): return JsonResponse({ ‘message‘: ‘get message‘ }) def post(self, request, *args, **kwargs): return JsonResponse({ ‘message‘: ‘post message‘ })
# drf:djangorestfraework => pip3 install djangorestfraework from rest_framework.views import APIView from rest_framework.request import Request from rest_framework.response import Response
# 1)安装drf:pip3 install djangorestfraework # 2)settings.py 注册app:INSTALLED_APPS = [..., ‘rest_framework‘] # 3)基于cbv完成满足RESTful规范的接口
#路由层 from app import views urlpatterns = [ url(r‘teachers/‘, views.Teachers.as_view()) ] #视图层 from rest_framework.views import APIView from rest_framework.response import Response class Teachers(APIView): def get(self, request, *args, **kwargs): # return JsonResponse({ # ‘status‘: 2, # ‘message‘: ‘请求成功‘ # }, json_dumps_params={‘ensure_ascii‘: False}) salary = request.GET.get(‘salary‘) print(salary) return Response({ ‘status‘: 2, ‘message‘: ‘get请求成功‘ }) # 前台发送数据的方式:formdata|urlencoded|json #drf的request都对其二次封装解析到request.data中 def post(self, request, *args, **kwargs): print(request) print(request._request) salary = request.data.get(‘salary‘) print(salary) return Response({ ‘status‘: 2, ‘message‘: ‘post请求成功‘ })
# as_view() # 核心走了父类as_view view = super(APIView, cls).as_view(**initkwargs) # 返回的是局部禁用csrf认证的view视图函数 return csrf_exempt(view) # dispatch(self, request, *args, **kwargs) # 二次封装request对象 request = self.initialize_request(request, *args, **kwargs) # 自定义request规则 self.initial(request, *args, **kwargs) # initialize_request(self, request, *args, **kwargs) # 原生request封装在request._request # initial(self, request, *args, **kwargs) # 认证 self.perform_authentication(request) # 权限 self.check_permissions(request) # 频率 self.check_throttles(request) # 在drf的request.py的模块中,对django的request进行二次封装 def __getattr__(self, attr): try: return getattr(self._request, attr) except AttributeError: return self.__getattribute__(attr) # 完成对django的request完全兼容
#models.py class Students(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() gender = models.CharField(max_length=8) def __str__(self): return self.name #自定义序列化类:为具体的类提供序列化 #my_serializers.py from rest_framework import serializers class StudentSerializers(serializers.Serializer) #1.如果没有source引入models的字段名,序列化字段名必须同models的字段名 #2.如果有source引入models的字段名,序列化字段名必须不同于models的字段名,目的是对外隐藏数据库的字段名 id = serializers.IntegerField() student_name = serializers.CharField(source=‘name‘) age = serializers.IntegerField() gender = serializers.CharField() # views.py from rest_framework.views import APIView from rest_framework.response import Response from app import models from app.my_serializers import StudentSerializers class Students(APIView): def get(self, request, *args, **kwargs): student_list = models.Students.objects.all() # 需要序列化多个对象,需要明确many=True student_list = StudentSerializers(student_list, many=True) return Response({ ‘status‘: 0, ‘message‘: ‘ok‘, ‘results‘: student_list.data }) def post(self, request, *args, **kwargs): name = request.data.get(‘name‘) age = request.data.get(‘age‘) gender = request.data.get(‘gender‘) student = models.Students.objects.create(name=name, age=age, gender=gender) student = StudentSerializers(student) return Response({ ‘status‘: 0, ‘message‘: ‘ok‘, ‘results‘: student.data }) #urls.py urlpatterns = [ url(r‘students/‘, views.Students.as_view()), ]
原文:https://www.cnblogs.com/ShenJunHui6/p/10872645.html