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" }}
PublisherSerializer