1.简介

什么是resful

resful是一个规范,说白了就是面向资源编程,把网络中所有的东西,想象成资源

2.规范

10条规范

1)API与用户的通信协议,总是用HTTPS协议:HTTPS比http安全

2)域名

https://api.example.com  尽量将API部署在专用域名(会存在跨域问题)https://example.org/api/  API很简单例如写一个查询所有图书的api接口:https://api.example.com/books                        https://127.0.0.1/api/books

3)版本

-版本:每个接口都应该有版本   URL,如:https://api.example.com/v1/    https://127.0.0.1/api/v2/books(推荐用这种)   请求头 跨域时,引发发送多次请求

4)路径

-路径,视网络上任何东西都是资源,均使用名词表示(可复数)   https://api.example.com/v1/books   https://api.example.com/v1/animals   https://api.example.com/v1/employees   不能这么写:      -获取所有图书:https://127.0.0.1/api/get_all_books      -新增一本书:https://127.0.0.1/api/add_book   同一都用这个:   https://api.example.com/v1/books

5)method

-method   GET      :从服务器取出资源(一项或多项)   POST    :在服务器新建一个资源   PUT      :在服务器更新资源(客户端提供改变后的完整资源)   PATCH  :在服务器更新资源(客户端提供改变的属性)   DELETE :从服务器删除资源谈到请求方法,这里需要提到一下幂等性幂等性:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个最简单的例子,那就是支付,用户购买商品使用支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱了,流水记录也变成了两条。这里简单介绍一下__getattr__:如果属性查找在实例以及对应的勒种失败,那么会调用到类的__getattr__函数,如果没有定义这个函数,那么会抛出异常。可以把__getattr__的作用理解为属性查找的最后一步,兜底。与__getattr__相对应的,还有个__setattr__,对象在属性赋值时,会执行这个函数
class Student:
    name = 'lqz'

    def __init__(self, age):
        self.age = age

    def __getattr__(self, item):
        return '你煞笔啊,没有这个属性'

    def __setattr__(self, key, value):
        print('setattr方法')
        self.__dict__[key] = value

    def __getitem__(self, item):
        print('getitem方法')
        return self.__dict__[item]

    def __setitem__(self, key, value):
        print('setitem方法')
        self.__dict__[key] = value

#setattr,赋值时会进行调用
#getattr,取不到对象的attr时会调用
#__getitem__ 对象A,取值A['name’]会调用
#__setitem__ 对象A设定值A['male’]会调用

A = Student(18)
A.num = '#调用__setattr__方法
print(A.num)
print(A['num'])#调用__getitem__方法
A['sex']='MALE'#调用__setitem__方法
print(A['sex'])
print(A.haha)#调用__getattr__方法

6)过滤

-过滤,通过在url上传参的形式传递搜索条件   https://api.example.com/v1/zoos?limit=10:指定返回记录的数量

7)状态码

请求回去,需要有状态码自定义状态码status: 100表示成功      101表示用户名密码错误      102我也不知道什么错误

8)错误处理

-错误处理,应返回错误信息,error当做key。   -{status:100,error:'错误信息写上'}

9)返回结果

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

10)Hypermedia API,resful API最好做到Hypermedia,即返回结果中提供链接,连向其他API

-Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API             方法,使得用户不查文档,也知道下一步应该做什么。      {         status:100         msg:成功         url:127.0.0.1/books/1      }   核心:返回结果中提供链接3.drf(django rest framework)框架(django的app)安装:djangorestframework它是一个app,要在咱的项目中用只是快速的构建resful规范的接口drf下request把原来的request包装进去了request.query_params这个是原来GET中的数据request.data是发方法,包装成了属性,前台传过来的body体重的数据,放在里面
from django.shortcuts import render,HttpResponse,redirect,reverse
from rest_framework.views import APIView
from app01 import models
from django.views import View
from django.http import JsonResponse

# Create your views here.

#写resful规范的接口,用fbv和cbv都可以

#这里使用rest_framework,是为了快速构建restful规范,即使不使用rest_framework,也是可以写的,只是麻烦一些

#不使用rest_framework版本
# class Books(View):
#     #获取所有图书
#     def get(self,request):
#         response={'status':100,'data':None}
#         books=models.Book.objects.all()
#         ll=[{'name':book.name,'price':book.price} for book in books]
#         response['data']=ll
#         return JsonResponse(response,safe=False)
#     def put(self,request,pk):
#         response={'status':100,'msg':'修改成功'}
#         #注意,django只处理了get和put,也就是只有这两个方法request.POST,request.GET能get到值
#         # name=request.POST.get('name')
#         # price=request.POST.get('price')
#         #这里无法get,所以直接去body体里去取
#
#         import json
#         data=json.loads(request.body.decode('utf-8'))
#         name=data.get('name')#相当于name=data['name'],不这么写只是我自己个人理解,防止万一没有值,程序崩溃
#         price=data.get('price')
#         ret=models.Book.objects.filter(pk=pk).update(name=name,price=price)
#         #按照resful规范这里需要返回一个改变后的完整的资源,但是resful是一个规范,是建议
#         #可以不按它的建议来,自己定义返回的结果
#         return JsonResponse(response,safe=False)

#使用restful的APIView类
class Books(APIView):
    #request.data是个方法,包装成了属性,前台传过来body体中的数据,放在里面
    #request.query_params 这个是原来GET中的数据

    #现在的request对象,已经不是原来django中的request对象了,它是rest_framework.request下的Request
    def put(self,request,pk):
        response={'status':100,'msg':'修改成功'}
        #以后再取数据,直接从request.data中取
        #前端传来json格式:
        #前端传来格式x-www-form-urlencoded格式:传来结果是<QueryDict: {'name': ['金瓶'], 'price': ['250']}>,type是<class 'django.http.request.QueryDict'>
        #这里应该是rest_framework内部进行了一些处理,将其转化了格式
        #前端传来格式json格式,传来结果是{'name': 'alex', 'price': '250'},type是<class 'dict'>
        #request.data不同编码格式过来,它可能是不同类的对象,但是用法都是一样的,可以用get
        print(request.data)
        print(type(request.data))
        return JsonResponse(response)

4.序列化django提供的序列化组件(不可控)
from django.core import serializers
    def get(self,request):
        response={'status':100,'data':None}
        books=models.Book.objects.all()
        #
        ret=serializers.serialize('json',books)
        print(ret)
        response['data']=ret
        return JsonResponse(response,safe=False)

drf提供的序列化组件

#drf序列化组件的使用
#1.导入drf的序列化类
from rest_framework.serializers import Serializer
from rest_framework import serializers
#2.写一个类继承它
class BookSerializer(Serializer):
    name=serializers.CharField()
    price=serializers.CharField()
    def get(self,request):
        books=models.Book.objects.all()
        # 第三步,实例化产生对象
        #instance=books是要序列化的queryset对象,many=True表示序列化多条
        #instance可以不写,按位置传.many=True一定要传
        # ser=BookSerializer(instance=books,many=True)
        ser=BookSerializer(books,many=True)
        #只序列化一个book对象的话,book也可以是单个对象,不是queryset对象
        # book=models.Book.objects.all().first()
        # ser=BookSerializer(book,many=False)
        #注意加上safa=False,拿到的是序列化之后的字典,里面有可能套了列表
        return JsonResponse(ser.data,safe=False)

5.规范使用序列化

在app中创建一个py文件,例如mySer.py

from rest_framework import serializers
from rest_framework.serializers import Serializer
from app01 import models

class AuthorSerializer(Serializer):
    name=serializers.CharField()
    sex=serializers.CharField()

class BookSerializer(Serializer):#BookSerializer这里在定义阶段,就要想好关联哪个表序列化哪些对象。
    #进到这个表里,将当做自己已经拿到了book对象,想要取哪个字段,直接在source里取
    #将对象返回实例化时,如果要修改字段名,可以在前面修改,后面再写上source='name',表示关联的字段
    xxx=serializers.CharField(source='name')
    #不指定字段名的话,这里前面的名字必须和models表里的字段名一样
    price=serializers.CharField()

    #这里publish在models里面是做了外键关联的,在Book表里存的是对象。所以这里返回的是Publish object。
    #如果要它返回出版社名字,方式一:可以在models下Publish表里自己定义str方法
    # publish=serializers.CharField()
    #方式二:
    # publish=serializers.CharField(source='publish.name')
    #Publish下的test函数也能被查出来,显示的是函数的执行结果,没什么卵用.
    test=serializers.CharField(source='publish.test')
    #SerializerMethodField可以指定一个方法
    #方法名:叫get_字段名,要传参数,参数是:当前的book对象
    publish=serializers.SerializerMethodField()
    def get_publish(self,obj):
        #obj是当前的book对象
        dic={'name':obj.publish.name,'email':obj.publish.email,'addr':obj.publish.addr}
        return dic
    #取这本书的所有作者
    #这样显示的是queryset对象,不太好,弃用
    # author=serializers.CharField(source='authors.all')

    authors=serializers.SerializerMethodField()
    def get_authors(self,book):
        aus=book.authors.all()
        #可以继续用序列化类,来处理
        auth_ser=AuthorSerializer(aus,many=True)
        return auth_ser.data

其中有个ModelSerlializer

from app01.models import Book
class BookSerializer(serializers.ModelSerializer):
    #必须写一个内部类,名字叫sMeta
    class Meta:
        model=Book#指定表
        fields='__all__'#指定字段
        #指定深度,可以理解为指定跨几张表。不推荐使用,特别影响效率,可控性查
        # depth=1
        #exclude=['publish']排除掉哪个字段
        #fields跟exclude不能连用
    #这时查到的一些关联外键的字段是数字,可以重写属性
    publish=serializers.CharField(source='publish.name')
    authors=serializers.SerializerMethodField()
    def get_authors(self,book):
        aus=book.authors.all()
        auth_ser=AuthorSerializer(aus,many=True)
        return auth_ser.data
												

resful规范的更多相关文章

  1. cvb源码分析,resful规范,drf,drf序列化组件,95

    1 CBV的源码分析 -Class Base View(基于类的视图) -Function Base View(基于函数的视图) -def as_view 类方法 -def view:类方法内部,闭包 ...

  2. Django drf:cbv源码、resful规范及接口、drf使用、response源码、序列化

    一.cbv源码分析 二.resful规范 三.django中写resful的借口 四.drf写resful的借口 五.APIVIew源码分析 六.drf之序列化 一.cbv源码分析 -CBV和FBV ...

  3. resful规范: 进行数据交换时的代码潜规则

    目前主流的三种web服务交互方案: REST (Representational State Transfer) 表征性状态转移 SOAP (Simple Object Access Protocol ...

  4. $Django RESTful规范

    一 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角度 ...

  5. cbv+resful+APIView源码分析

    CBV源码分析 1概念:什么是cbv和fbv 已经什么是API class bass View ---基于类的视图 function bass View ---基于函数的视图 API(Applicat ...

  6. restful规范和drf模块

    restfu1规范 它是一个规范,面向资源架构 10条规范: 1.api与用户的通信协议,总是使用https协议 api网上提供的接口 2.域名: 尽量将api部署在专用域名(会存在跨域问题) API ...

  7. Django框架(十七)-- CBV源码分析、restful规范、restframework框架

    一.CBV源码分析 1.url层的使用CBV from app01 import views url(r'book/',views.Book.as_view) 2.as_view方法 as_view是 ...

  8. Django框架(十八)—— CBV源码分析、restful规范、restframework框架

    目录 CBV源码分析.restful规范.restframework框架 一.CBV源码分析 1.url层的使用CBV 2.as_view方法 3.view方法 4.dispatch方法(可以在视图层 ...

  9. Python-Django-Djangorestframwork

    1 CBV源码分析(cbv和fbv) 1 在views中写一个类,继承View,里面写get方法,post方法 2 在路由中配置: url(r'^test/', views.Test.as_view( ...

随机推荐

  1. mysql常用语句和函数

    mysql语句如果长期不写,就会忘掉,所以要时常复习,温故而知新. 1.select length("中国人"),select char_length("中国人" ...

  2. 【react】---pureComponent的理解

    一.pureComponent的理解  pureComponent表示一个纯组件,可以用来优化react程序.减少render函数渲染的次数.提高性能 pureComponent进行的是浅比较,也就是 ...

  3. Python不支持函数重载

    函数重载与Python: 函数重载的好处就是不用为了不同的参数类型或参数个数,而写多个函数.多个函数用同一个名字,但参数表,即参数的个数和数据类型可以不同.调用的时候,虽然方法名字相同,但根据参数表可 ...

  4. ThinkPHP框架 【 AJAX方法返回 】 例子:简单添加一条数据 和 查询一个表里的数据

    注:thinkphp使用ajax和之前使用ajax的方法一样,不同点在于之前的ajax中的url指向了一个页面,而thinkphp里面的url需要指向一个操作方法. 在模块控制器Controller文 ...

  5. 常见的压缩文件格式案例tarZ

    在AIX上最常见的压缩文件就是.tar压缩格式的文件了.  而除了tar文件以外,有时会遇到数据是用其它的压缩文件格式,所以偶顺手整理了一些常见的压缩文件格式,在AIX要怎么解压缩 : 一. .tar ...

  6. POJ 1451 - T9 - [字典树]

    题目链接:http://bailian.openjudge.cn/practice/1451/ 总时间限制: 1000ms 内存限制: 65536kB 描述 Background A while ag ...

  7. [No0000103]JavaScript-基础课程3

    在 JavaScript 中,函数的参数是比较有意思的,比如,你可以将任意多的参数传递给一个函数,即使这个函数声明时并未制定形式参数 function adPrint(str, len, option ...

  8. [No0000F8]override和new的区别

    override 1. override是派生类用来重写(或覆盖)基类中方法的: 2. override不能重写非虚方法和静态方法: 3. override只能重写用virtual.abstract. ...

  9. 为什么css定位雪碧图(合成图)都要以负号开头?

    (1)正常来说 定位坐标是以 合成图片 左上角这个点作为原点(0px,0px)开始读取的, 而你的图片全都在坐标系的 第四象限 background-position: x y:(x,y为数值或百分比 ...

  10. python:turtle绘图模块

    turtle模块 海龟绘图(Turtle Graphics),python内置模块,非常简单好玩的一个库. 一.导入库 import turtle from turtle import * 二.画布的 ...