Python之Django rest_Framework


Django Rest Framework

一、rest api

   a、api就是接口

        如: - http://www.oldboyedu.com/get_user/

               - http://www.oldboyedu.com/get_users/

   b、api的两个用途

        1、为别人提供服务

        2、前后端分离

二、restful

    a、--字面意思:表征状态转移

    b、面向资源编程,对互联网上的任意东西都视为资源

         如:- http://www.oldboyedu.com/get_user/

                - http://www.oldboyedu.com/get_img/1.png

普通的API:

    如:

姑娘列表: http://www.oldboyedu.com/get_girls/ http://www.oldboyedu.com/add_girl/ http://www.oldboyedu.com/del_girl/1/ http://www.oldboyedu.com/update_girl/1/

restful api:

姑娘列表: http://www.oldboyedu.com/girls/ GET: 获取 POST: 添加 PUT: 更新 DELETE:删除

三、restful规范

      ---URL

      ---url名词

路径,视网络上任何东西都是资源,均使用名词表示(可复数)
  https://api.example.com/v1/zoos
  https://api.example.com/v1/animals
  https://api.example.com/v1/employees

      ---status状态码

200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
常用状态码

      ---提交方式

  • GET      :从服务器取出资源(一项或多项)
  • POST    :在服务器新建一个资源
  • PUT      :在服务器更新资源(客户端提供改变后的完整资源)
  • PATCH  :在服务器更新资源(客户端提供改变的属性)
  • DELETE :从服务器删除资源

      ---错误信息

状态码是4xx时,应返回错误信息,error当做key。 { error: "Invalid API key" }

      ---版本

URL,如:https://api.example.com/v1/ 请求头 跨域时,引发发送多次请求

      ---Hypermedia link,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。

{"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json" }}

         ---域名

https://api.example.com 尽量将API部署在专用域名(会存在跨域问题) https://example.org/api/ API很简单

         ---过滤,通过在url上传参的形式传递搜索条件

https://api.example.com/v1/zoos?limit=10:指定返回记录的数量 https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置 https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数 https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序 https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件

         ---返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范

GET /collection:返回资源对象的列表(数组)   GET /collection/resource:返回单个资源对象 POST /collection:返回新生成的资源对象 PUT /collection/resource:返回完整的资源对象 PATCH /collection/resource:返回完整的资源对象 DELETE /collection/resource:返回一个空文档

 

- 姑娘: 方式一: http://www.oldboyedu.com/girls/ http://www.oldboyedu.com/girls/1/ GET: 获取 POST: 添加 PUT: 更新 DELETE:删除 方式二: http://www.oldboyedu.com/girls/ - 姑娘列表 http://www.oldboyedu.com/girl/1/ - 单独一个

四、基于Django做API

      ---FBV

      ---CBV

路由系统:

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^users/', views.users),
url(r'^user/(\d+)', views.user),
]

FBV视图:

from django.shortcuts import render,HttpResponse
import json

def users(request):
response = {'code':1000,'data':None}
response['data'] = [
{'name':'lg','age':19},
{'name':'mqj','age':20},
{'name':'wxp','age':5},
]
return HttpResponse(json.dumps(response),status=200)

def user(request,pk):
if request.method == "GET":
return HttpResponse(json.dumps({'name':'lg','age':19}))
elif request.method == "POST":
return HttpResponse(json.dumps({'code':1111}))
elif request.method == "PUT":
pass
elif request.method == "DELETE":
pass

CBV:

路由系统:

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
      url(r'^admin/', admin.site.urls),
      url(r'^users/', views.UsersView.as_view()),
      url(r'^user/(\d+)', views.UserView.as_view()),
】

CBV视图:

from django.shortcuts import render,HttpResponse from django.views import View import json class UsersView(View): def get(self,request): response = {'code': 1000, 'data': None} response['data'] = [ {'name': 'lg', 'age': 19}, {'name': 'mqj', 'age': 20}, {'name': 'wxp', 'age': 5}, ] return HttpResponse(json.dumps(response), status=200) class UserView(View): def dispatch(self, request, *args, **kwargs): # method = request.method.lower() # func = getattr(self,method) # ret = func() # return ret ret = super(UserView,self).dispatch(request,*args, **kwargs) return ret def get(self,request,pk): print(request,type(request)) return HttpResponse(json.dumps({'name': 'lg', 'age': 19})) def post(self,request,pk): return HttpResponse(json.dumps({'name': 'lg', 'age': 19})) def put(self,request,pk): return HttpResponse(json.dumps({'name': 'lg', 'age': 19})) def delete(self,request,pk): return HttpResponse(json.dumps({'name': 'lg', 'age': 19}))

 

五、 基于Django Rest Framework框架实现

    a、安装:pip3 install djangorestframework -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com

    b、基本流程

url.py  from django.conf.urls import url, include  from web.views.s1_api import TestView urlpatterns = [ url(r'^test/', TestView.as_view()), ]
views.py
from rest_framework.views import APIView from rest_framework.response import Response class TestView(APIView): def dispatch(self, request, *args, **kwargs): """ 请求到来之后,都要执行dispatch方法,dispatch方法根据请求方式不同触发 get/post/put等方法 注意:APIView中的dispatch方法有好多好多的功能 """ return super().dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): return Response('GET请求,响应内容') def post(self, request, *args, **kwargs): return Response('POST请求,响应内容') def put(self, request, *args, **kwargs): return Response('PUT请求,响应内容')

    c、基于Token的用户认证

url.py:

from django.conf.urls import url
from django.contrib import admin
from app01 import views
from app02 import views as app02_view
urlpatterns = [
        # django rest framework
    url(r'^auth/', app02_view.AuthView.as_view()),
    url(r'^hosts/', app02_view.HostView.as_view()),

]
url.py

views.py

from django.views import View

from rest_framework.views import APIView
from rest_framework.authentication import SessionAuthentication
from rest_framework.authentication import BasicAuthentication
from rest_framework.authentication import BaseAuthentication
from rest_framework.request import Request
from rest_framework.exceptions import APIException
from rest_framework.response import Response


from app02 import models
import hashlib
import time

# class MyBasicAuthentication(BasicAuthentication):
#     def authenticate_credentials(self, userid, password, request=None):
#         if userid == 'alex' and password == '123':
#             return ('alex','authaaaaaaaaaaaa')
#         raise APIException('认证失败')

class AuthView(APIView):
    authentication_classes=[]
    def get(self,request):
        """
        接收用户名和密码
        :param request: 
        :return: 
        """
        ret = {'code':1000,'msg':None}

        user = request.query_params.get('user')
        pwd = request.query_params.get('pwd')

        obj = models.UserInfo.objects.filter(username=user,password=pwd).first()
        if not obj:
            ret['code'] = 1001
            ret['msg'] = "用户名或密码错误"
            return Response(ret)
        # 创建随机字符串
        ctime = time.time()
        key = "%s|%s" %(user,ctime)
        m = hashlib.md5()
        m.update(key.encode('utf-8'))
        token = m.hexdigest()

        # 保存到数据
        obj.token = token
        obj.save()

        ret['token'] = token
        return Response(ret)


class HostView(APIView):

    def get(self,request,*args,**kwargs):
        # 原来request对象,django.core.handlers.wsgi.WSGIRequest
        # 现在的request对象,rest_framework.request.Request\
        self.dispatch
        print(request.user)
        print(request.auth)
        return Response('主机列表')
views.py
django-rest-framework
            - 认证
                - 局部
                    class MyAuthentication(BaseAuthentication):

                        def authenticate(self, request):
                            # return None ,我不管
                            token = request.query_params.get('token')
                            obj = models.UserInfo.objects.filter(token=token).first()
                            if obj:
                                return (obj.username,obj)
                            raise APIException('用户认证失败')
                            
                            
                    class AuthView(APIView):
                        authentication_classes=[MyAuthentication,]
                - 全局
                     #配置文件
                    REST_FRAMEWORK = {
                        'UNAUTHENTICATED_USER': None,
                        'UNAUTHENTICATED_TOKEN': None,
                        "DEFAULT_AUTHENTICATION_CLASSES": [
                            "app02.utils.MyAuthentication",
                        ],
                    }

                    
                    class HostView(APIView):

                        def get(self,request,*args,**kwargs):
                            # 原来request对象,django.core.handlers.wsgi.WSGIRequest
                            # 现在的request对象,rest_framework.request.Request
                            print(request.user)
                            print(request.auth)
                            return HttpResponse('主机列表')

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM