1,DRF-序列化内容的准备-django的序列化-外键关系序列化以及反序列化-PATCH请求


1,DRF-序列化内容的准备-django的序列化-外键关系序列化以及反序列化-PATCH请求

 https://www.cnblogs.com/GGGG-XXXX/articles/9258310.html --RSTful规范,

https://www.cnblogs.com/GGGG-XXXX/articles/9568816.html --DRF的序列化

 

https://www.cnblogs.com/wupeiqi/articles/7805382.html        --restful规范,wusir

 

Django中间件跟版本有关系,不同的版本,执行,那几个中间件流程不一样,

 

csrf_token就放在prcess_view里面,

去请求体或者cookie中获取token,做校验,

 

api其实就是url,就是接口,

 

/

https://www.cnblogs.com/GGGG-XXXX/articles/9258310.html--RESTful

rest:前后端交互的 一种规范,            
前后端传输的是资源的表述,并不是资源的本身,            

rest 是面向资源的
soap是面向操作的            

回调接口跟api接口是不一样的
执行.as_view()方法,自己没写,上view里面去找,

as_view:return view
view:return self.dispatch
dispatch:return handler,  进行了请求方法的判断,
            
json序列化不了queryset类型,序列化不了时间类型
JsonResponse可以序列化时间类型,但是序列化不了外键关系,
            
            
前端传过来的数据都会走序列化器进行反序列化, 并进行验证,           
            
            serializers.py
            
            
序列化的时候放queryset,  

 

 /

many=True:序列化多个对象,就要写这个.如果是对象(get,first,last)就不用了,在外键那边,就是区分是多对多,而不是外键
序列化之后的数据是放在data里面的.

source='get_category_display' #显示的是汉字了,不再是对应的数字了,(选择字段那个)
required=False,就是反序列化的时候,字段不用进行校验,(前端传过来的数据)
正序:
    后端的数据,需要序列化之后,给前端去展示,
反序列化:    
    前端提交的数据,也需要反序列化,转换成后端可以处理的数据格式,
    反序是不走read_only=True,required=False的;
    
正序跟反序的时候字段类型不统一,导致,有的字段需要正序,有的需要反序;
    read_only=True,只正序的时候用(后端向前端传数据);
    write_only=True,只反序的时候用,(前端传数据给后端);

post提交的数据:
    post提交的数据,不再是request.POST.get('xx')来获取了,而是在request.data,因为继承的类不一样了
    save的时候,是调用的create的方法,
    
put是全部更新,
patch是局部更新    
    ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True)
    partial=True:是允许部分验证,
    save的时候,是调用的update的方法,
    
post跟patch的区别-save的时候,调用的方法是不一样的.    

instance就是根据条件获取到的对象.(例如id=4)

 

/

 

 

postman伪造发各种请求,

http://127.0.0.1:8000/students/


    RESTful
        REST风格  设计原则和约束条件
            -- 资源
            -- 统一资源定位符 URL
                统一资源标识符 URI
            -- 统一资源的接口
                -- 根据HTTP请求方式的不同对资源进行不同的操作
            -- 前后端传输的是资源的表述
            -- 页面展现的资源的状态
            -- 超链接的指引来告诉用户接下来有哪些状态可以进去
        RESTful架构 10条
            -- 核心思想
                -- 面向资源去编程 url中尽量用名词
                -- 根据HTTP请求方式的不同对资源进行不同的操作
            -- url体现
                -- 版本
                -- api
                -- 过滤条件?page=1
                -- 尽量用https
            -- 返回
                -- 携带状态码
                -- 返回值
                    -- get 返回查询的所有或者单条数据
                    -- post 返回值新增的那条数据
                    -- put/patch  返回更新的那条数据
                    -- delete 空
                -- 返回携带错误信息
                -- 携带超链接
    FBV和CBV的区别
        --     def dispatch(self, request, *args, **kwargs):
                    # Try to dispatch to the right method; if a method doesn't exist,
                    # defer to the error handler. Also defer to the error handler if the
                    # request method isn't on the approved list.
                    # GET POST -- get post
                    # self.get  self.post
                    # 判断你的请求方式是否在允许的http请求方式里
                    # 如果合法 self.get
                    if request.method.lower() in self.http_method_names:
                        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
                    else:
                        handler = self.http_method_not_allowed
                    return handler(request, *args, **kwargs)
                
主要内容:
    json 轻量级的数据交互格式
        -- Python --- json  序列化
        -- json --- Python  反序列化
    Django实现的序列化
        -- .values 和JsonResponse 
            -- 自己去构建想要的数据结构
        -- django的 serialize
            -- 废话太多 外键关系依然需要自己去构建
    DRF框架 -- 下载 -- pip install djangorestframework -- 在settings里注册app -- “rest_framework”
    DRF序列化
        -- 声明一个序列化器
            from rest_framework import serializers

            class BookSerializer(serializers.Serializer):
                # 这里声明想要序列化的字段
                id = serializers.IntegerField()
                title = serializers.CharField(max_length=32)
        -- 视图
            -- 视图类继承APIView
            -- 返回 Response
            -- ser_obj = BookSerializer(query_set, many=True)
            -- ser_obj.data
    DRF的反序列化
        -- 序列化器
            -- read_only
            -- write_only
            -- require=Flase
            -- 正序和反序列化的时候字段类型不同的时候
            -- 重写create方法
                -- ORM的操作进行新增数据
        -- 视图
            --     def post(self, request):
                        book_obj = request.data
                        print(request.data)
                        ser_obj = BookSerializer(data=book_obj)
                        if ser_obj.is_valid():
                            print(ser_obj.validated_data)
                            ser_obj.save()
                            return Response(ser_obj.validated_data)
                        else:
                            return Response(ser_obj.errors)
    DRF的更新操作
        -- 序列化器
            -- 写update方法
        -- 视图
                def patch(self, request, id):
                    book_obj = Book.objects.filter(id=id).first()
                    ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True)
                    if ser_obj.is_valid():
                        ser_obj.save()
                        return Response(ser_obj.validated_data)
                    else:
                        return Response(ser_obj.errors)


 

需要引入的,

from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, JsonResponse
from .models import Book, Publisher
from django.core import serializers
import json    
    
    
from rest_framework.views import APIView #view里需要引入的, from rest_framework.response import Response from .serializers import BookSerializer from rest_framework import serializers    #在自定义的序列化器里,需要引入的,

 

 

 

 

 

 需要注册app,不注册会报错,

 

 

 

 

 

json不是语言就是格式,

 

 /

 

/

python与json可以转化的数据类型

 

 

/

 /

 拿django写接口,

 

引入的区别,

对比两者引入的区别,

from django.shortcuts import render,HttpResponse from django.http import JsonResponse

 

HttpResponse与JsonResponse的区别, 

JsonResponse就是继承的HttpResponse,JsonResponse,有封装了对时间的序列化方法,

 

使用DRF框架进行序列化,步骤,

第一步 下载 pip install djangorestframework
第二步 在settings注册一个app  “rest_framework”
第三步 新建一个py文件,声明一个序列化器
第四步,在视图函数里面引入第三步的py文件,

 

 JsonResponse 的使用

from django.shortcuts import render
from django.views import View
from django.http import HttpResponse, JsonResponse
from app01 import models
import json

def login(request):
    book=models.Book.objects.all()
    print(book,book[0])
    book_lst=models.Book.objects.all().values('id','title','put_time')
    #json不能序列化queryset的类型,需要强制类型转换一下,
    book_lst=list(book_lst)
    #safe=False,保证不报错,ensure_ascii保证可以是汉字
    return JsonResponse(book_lst,safe=False,json_dumps_params={'ensure_ascii':False})

/

 

 /

第一版:

把出版社封装成一个字典

def login(request):
    book=models.Book.objects.all()
    print(book,book[0])
    book_lst=models.Book.objects.all().values('id','title','put_time','publisher')
    book_lst = list(book_lst)
    
    #有无下面for循环的区别
    for book in book_lst:
        pub=Publisher.objects.filter(id=book['publisher']).first()
        book['publisher']={
            'id':pub.id,
            'title':pub.title
        }
    return JsonResponse(book_lst,safe=False,json_dumps_params={'ensure_ascii':False})

//

 

 

 

第二版

 

用django的serialize方法实现的序列化,可以序列化queryset,依然不能序列化外键关系

#第二版 用django的serialize方法实现的序列化,数据冗余,
from django.core import serializers

def login(request):
    book_list=Book.objects.all()
    ret=serializers.serialize('json',book_list,ensure_ascii=False)
    return HttpResponse(ret)

显示不够友好,不是想要的,

 

 

 

 第三版:使用DRF,需要先下载安装

https://blog.csdn.net/HH2030/article/details/81009071

 

 

 代码

 

#view里的代码


from
rest_framework.views import APIView from rest_framework.response import Response # 注意返回的时候,返回的数据,返回的 是Response了, from .serializers import BookSerializer
注意,此处继承的是APIView
class BookAPIView(APIView): def get(self,request): book_list=Book.objects.all() #many=True,表示序列化多个字段,要是单个的对象,就不用many=True了, ser_obj=BookSerializer(book_list,many=True) #序列化成功的数据是在ser_obj.data里面, return Response(ser_obj.data)

///

序列化器里面的代码

from rest_framework import serializers class PublisherSerializer(serializers.Serializer):
    id=serializers.IntegerField()
    title=serializers.CharField(max_length=32)

class AuthorSerializer(serializers.Serializer):
    id=serializers.IntegerField()
    name=serializers.CharField(max_length=32)


class BookSerializer(serializers.Serializer):
    # 变量名称要跟models里面的字段名称一致,

    id=serializers.IntegerField()
    title=serializers.CharField(max_length=32)
    #source='get_category_display' 获取到分类的中文,可以跟ORM的各种操作,
    category=serializers.CharField(max_length=32,source='get_category_display')
    put_time=serializers.DateField()

    #序列化外键关系,此处写的是定义的类名,PublisherSerializer,,,
    publisher=PublisherSerializer()
    #many=True用来表名序列化的是多对多的关系,
    authors=AuthorSerializer(many=True)

 /

 

 

 /

 

/

 

 

 

 

 

 

 

 

read_onlly与write_only的区别,

read_only是正序

反序是不走read_only=True,required=False ,

参考内容:https://blog.csdn.net/l_vip/article/details/79156113

 

提交的post进行save的时候,需要调用create方法,create写在自己创建的那个序列化器里面,

 /

 

 

/

正序与反序的区别

 

 

/

 前端传回的数据,

/

进行反序列化,构建前端传回的数据的数据格式,

提交成功,返回提交的信息,

  

 

/

 创建数据

/

提交的数据与验证通过的数据,

 

/

 错误信息的提示

 

 

 /

 patch 局部更新,调用的是update方法

 

 

 

patch进行局部更新,put进行全部更新,

 

 

 

restful规范

10条

1,使用https,安全,----------API与用户的通信协议,总是使用HTTPs协议。
2,域名 
    https://api.example.com                         尽量将API部署在专用域名(会存在跨域问题)
    https://example.org/api/                        API很简单,   ---------------建议用这个,
3,版本
    URL,如:https://api.example.com/v1/   -----用这个,
    请求头   跨域时,引发发送多次请求
    
4,路径,视网络上任何东西都是资源,均使用名词表示(可复数)-------面向资源编程
    https://api.example.com/v1/zoos
    https://api.example.com/v1/animals
    https://api.example.com/v1/employees    
    
5,method
    GET      :从服务器取出资源(一项或多项)
    POST    :在服务器新建一个资源
    PUT      :在服务器更新资源(客户端提供改变后的完整资源)  --------全部更新
    PATCH  :在服务器更新资源(客户端提供改变的属性)          --------局部更新
    DELETE :从服务器删除资源    
    
6,过滤,通过在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:指定筛选条件 


7,状态码,
    200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
    201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
    202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
    204 NO CONTENT - [DELETE]:用户删除数据成功。
    301 永久重定向,
    302 临时重定向,
    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 - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

    简单认为:200系列是成功的,300系列是重定向的,400系列是客户端的错误,500系列是服务器端的错误
    更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html   
    
    为什么要状态码:状态码是给用户做提示的, -----*****----*****
    
    与前端交互,要状态码还是要code
    def get(requset):
    code={
        'code':1000,
        'msg':'xxx'
    }
    return HttpResponse(json.dumps(code),status=201)
    
8,错误处理

    错误处理,状态码是4xx时,应返回错误信息,error当做key。
        {
        error: "Invalid API key"
    }
        
9,返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。
    GET /collection:返回资源对象的列表(数组)
    GET /collection/resource:返回单个资源对象
    POST /collection:返回新生成的资源对象
    PUT /collection/resource:返回完整的资源对象
    PATCH /collection/resource:返回完整的资源对象
    DELETE /collection/resource:返回一个空文档
        

   
10,Hypermedia API,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"
    }}
10条规范

 

 
PublisherSerializer


免责声明!

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



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