2021-5-17 <Django框架 五---接口开发>

目录

 

动静分离

动静不分离

动静分离(前后端分离)

Restful与接口文档

CORS问题

FBV与CBV

F function(用的很少)

C class

Django-RESTfulFramewrok

安装

快速开始

    序列化:

            视图:

            路由:


动静分离

动:动态数据

静:静态文件

动静不分离

随着技术的发展:

  1. 前端技术越来越复杂,后端的学习成本变高了。

  2. 使用web技术终端变多了,比如:pc,小程序,移动端

动静分离(前后端分离)

Restful与接口文档

 

为了规范接口开发,后端工程师需要遵循RestFul风格和编写接口文档

Restful:(英文:Representational State Transfer,简称REST)是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义返回数据。

  1. API与用户的通信协议,总是使用HTTPS协议。

  2. 在域名上和常规的页面有区分,例如:

    https://www.ujiuye.com  网页地址
    https://www.ujiuye.com/api/v1.0/  接口地址
  3. 规范:在url上不可以出现动词
    对学员信息编写接口
    https://www.ujiuye.com/api/v1.0/get_student/  get就是动词,不好
    GET https://www.ujiuye.com/api/v1.0/student/  get请求方式,返回所有学员信息
    GET https://www.ujiuye.com/api/v1.0/student/1/   get请求方式,返回id为1的学员信息
    GET https://www.ujiuye.com/api/v1.0/student/?age=12   get请求方式,返回age为12的学员信息
    POST https://www.ujiuye.com/api/v1.0/student/  post请求方式,保存学员形象
    PUT https://www.ujiuye.com/api/v1.0/student/1/  put请求方式,修改id为1的学员信息
    DELETE https://www.ujiuye.com/api/v1.0/student/1/  delete请求方式,删除id为1的学员

     

  4. 服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。
    200 OK - [GET]:服务器成功返回用户请求的数据
    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 - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
    410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
    422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
    500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

     

  5. 针对不同操作,服务器向用户返回的结果应该符合以下规范。
    GET  /collection:返回资源对象的列表(数组)
    GET  /collection/resource:返回单个资源对象
    POST /collection:返回新生成的资源对象
    PUT  /collection/resource:返回完整的资源对象
    DELETE /collection/resource:返回一个空文档

     

  6. RESTful API最好做到Hypermedia(即返回结果中提供链接,连向其他API方法),使得用户不查文档,也知道下一步应该做什么。接口文档:网关:接口地址,比如:

    https://www.ujiuye.com/api/v1.0/

    接口描述:

    支持接口的功能和效果

    请求描述

    请求的格式,请求需要携带的参数,参数的含义

  7. 参考

    https://opendocs.alipay.com/apis

     

CORS问题

同源问题

一个源的定义:如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。(举路由例子来说明)

同源策略:同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。注意:浏览器只会阻止ajax和form请求,不会阻止src请求

接口地址:
https://inedx.com/api/v2.9
https://helloworld.com
这样:
https://helloworld.com的网页无法请求https://inedx.com/api/v2.9的数据,需要开发者手动解除同源问题。

方法1:

使用django-cors-headers方法

  1. 安装cors模块:pip install django-cors-headers
  2. 安装应用:settings当中INSTALLED_APPS部分添加:corsheaders
  3. settings当中MIDDLEWARE_CLASSES添加:'corsheaders.middleware.CorsMiddleware',
  4. 配置白名单:CORS_ORIGIN_WHITELIST
  5. 后端是否支持跨域的cookie的操作:CORS_ALLOW_CREDENTIALS
  6. 后端允许的请求方法:CORS_ALLOW_METHODS
  7. 后端允许的请求头内容:CORS_ALLOW_HEADERS

方法2:

response["Access-Control-Allow-Origin"] = "http://192.168.10.101:8080"
response["Access-Control-Allow-Credentials"] = "true"
responsereutrn response["Access-Control-Allow-Methods"] = "GET,POST"
response["Access-Control-Allow-Headers"] = "Origin,Content-Type,Cookie,Accept,Token"

 

FBV与CBV

F function(用的很少)

FBV:函数视图,视图功能是一个函数,编写简单,但是不适合复杂的代码。

from django.http import JsonResponse

def books(request):
    """
    FBV 函数视图
    :param request:
    :return:
    """
    return JsonResponse({"code": 200,"data": []})

C class

CBV: 类视图,使用类进行视图功能的编写,比较笨重。

from django.views import View
from django.http import JsonResponse

class BookView(View):
    def __init__(self,**kwargs):
        super(BookView).__init__(**kwargs)
        self.result = {
            "code": 200,
            "data": [

            ]
        }
    def get(self,request):
        self.result["data"].append("get 请求")
        return JsonResponse(self.result)


    def post(self,request):
        self.result["data"].append("post 请求")
        return JsonResponse(self.result)

    def put(self,request):
        self.result["data"].append("put 请求")
        return JsonResponse(self.result)

    def delete(self,request):
        self.result["data"].append("delete 请求")
        return JsonResponse(self.result)

路由配置

from django.contrib import admin
from django.urls import path,re_path
from Dj.views import *
urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', BookView.as_view()),
]

接口辅助工具 postman:

类视图的csrf问题:

from django.views.decorators.csrf import csrf_exempt
#csrf_exampt 避免csrf保护
urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', csrf_exempt(BookView.as_view())),
    # path('books/', books),

]

完整的接口代码

class BookView(View):
    def __init__(self,**kwargs):
        super(BookView).__init__(**kwargs)
        self.result = {
            "code": 200,
            "data": [

            ]
        }
    def serialize_book(self,obj):
        result = {
            "id": obj.id,
            "title": obj.title,
            "author": obj.author,
            "type": obj.type,
            "description": obj.description,
            "public_time": obj.public_time,
            "picture": "http://127.0.0.1:8000" + obj.picture.url.replace("/media/","/static/")
        }
        return result

    def get(self,request,id = 0):
        """
        books/    返回所有书籍
        books/1   返回id为1的书籍
        :param request:
        :return:
        """
        if id:
            try:
                book = Books.objects.get(id = id)
            except Exception as e:
                self.result["code"] = 400
                self.result["data"].append(str(e))
            else:
                self.result["data"].append(
                    self.serialize_book(book)
                )
        else:
            search_key = request.GET.dict()
            books = Books.objects.filter(**search_key)
            self.result["data"] = [self.serialize_book(i) for i in books]
        return JsonResponse(self.result)

    def post(self,request):
        data = request.POST
        author = data.get("author")
        type = data.get("type")
        description = data.get("description")
        public_time = data.get("public_time")
        picture = request.FILES.get("picture")

        books = Books()
        books.author = author
        books.type = type
        books.description = description
        books.public_time = public_time
        books.picture = picture
        books.save()

        self.result["data"].append(
            self.serialize_book(books)
        )

        return JsonResponse(self.result)

    def put(self,request,id):
        """
        获取put数据
        """
        data = MultiPartParser(
            request.META,
            request,
            request.upload_handlers
        ).parse()[0].dict() #接收put数据

        books = Books.objects.filter(id = id) #查询
        books.update(**data) #更新

        self.result["data"] = [self.serialize_book(i) for i in books]

        return JsonResponse(self.result)

    def delete(self,request,id):
        try:
            book = Books.objects.get(id = id)
        except Exception as e:
            self.result["code"] = 400
            self.result["data"].append(str(e))
        else:
            book.delete()
        return JsonResponse(self.result)

Django-RESTfulFramewrok

通常三方开发的模块都是以django App的形式出现的。

Django-restframework是进行接口快速开发的Django插件,加快了开发效率,减少了代码重构的可能

安装

pip install djangorestframework

快速开始

1.  配置settings                             

 

2.  编写序列化文件                   

    

3.  编写类视图                               

 

4.  编写路由                                   

 

上述案例完成了最基本的项目功能,接下来需要了解以下内容

了解restful的三个部分

序列化:

序列化最先解决的是将ORM数据实例转换为字典类型的问题。但是在发展的过程当中发现,反序列化也很重要。

快速序列化,使用ModelSerializer,这个方法基础了基础的Serializer方法,实现了对数据模型的快速遍历。

restful反序列化实现了数据的校验

  1. 使用validate_字段
    class BooksSerializer(serializers.Serializer):
        """
        完成关于项目的序列化
        """
        title = serializers.CharField()
        author = serializers.CharField()
        type = serializers.CharField()
        description = serializers.CharField()
        public_time = serializers.DateField()
        # picture = serializers.ImageField()
        def validate_title(self,value): #只能对对应的字段进行校验
            if "坏蛋" in value:
                raise serializers.ValidationError("敏感词错误")
            return value

     

  2. 使用validate
    class BooksSerializer(serializers.Serializer):
        """
        完成关于项目的序列化
        """
        title = serializers.CharField()
        author = serializers.CharField()
        type = serializers.CharField()
        description = serializers.CharField()
        public_time = serializers.DateField()
        # picture = serializers.ImageField()
        def validate(self, attrs): #可以对当前序列化的所有字段校验
            print(attrs)

     

  3. 使用字段的validators属性
    def title_valid(value):
        if "坏蛋" in value:
            raise serializers.ValidationError("敏感词错误")
        return value
    
    class BooksSerializer(serializers.Serializer):
        """
        完成关于项目的序列化
        """
        title = serializers.CharField(validators=[title_valid])
        author = serializers.CharField()
        type = serializers.CharField()
        description = serializers.CharField()
        public_time = serializers.DateField()

     

视图:

在restful当中,将试图划分成了两个部分,一部分是配置部分,用来加载各种过滤器,比如分页,比如分组查询。另外的的一部分用来做具体功能的实现。掌握各种类的拼装

路由:

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值