Python之Django rest_Framework(2)

来源:https://www.cnblogs.com/mengqingjian/archive/2018/02/07/8428053.html
-Advertisement-
Play Games

rest_Framework的規範: 按順序:它的method的不同,原來沒有考慮,原來是url區分,現在通過method來區分,method的不同提交方式不同,緊接著一般是面向資源的就是把url變成名詞,接下就是返回值,以前沒有考慮狀態碼,現在有考慮狀態碼。(一般有get,post方法,還有put ...


實例化:
v1 = ["view.xxx.path.Role","view.xxx.path.Group",]    可以迴圈,迴圈出來的每一個不能實例化
如果把v1迴圈弄成每一個對象列表,通過rsplit切割,在通過importlib.import_module拿到每一個路徑,在通過getattr把它的類名拿過來,
這個類加括弧就是實例化想
for item in v1: m = importlib.import_module('view.xxx.path') cls = getattr(m,'Role') cls() from view.xxx.path import Role,Group v2 = [Group,Role] 這個可以迴圈每一個實例化 for item in v2: #迴圈V2的每一個元素加括弧,就是實例化 item()

rest_Framework的規範:

    按順序:它的method的不同,原來沒有考慮,原來是url區分,現在通過method來區分,method的不同提交方式不同,緊接著一般是面向資源的就是把url變成名詞,接下就是返回值,以前沒有考慮狀態碼,現在有考慮狀態碼。(一般有get,post方法,還有put,delete等方法)

 

一、Django rest_Framework框架

   ----為什麼用Django rest_Framework框架?

            ----首先沒有Django rest_Framework框架用django也是可以做出來的,只不過它為我們提供一些API常用的功能,比如:(認證,許可權,限流,有了這些我們只需要寫個類已配置,它就能當都市圖用,還能全局配置,如果自己寫還得寫中間件,寫裝飾器來實現,通過Django rest_Framework框架,他已經把規則寫好,只需要寫類,只需實現方法,返回值就可以實現了一部分功能。

  ----設計比較好

            ----單獨視圖+全局配置 =>Dajngo中間件(importlib/反射)=>動態配置課擴展(簡訊,郵件,微信等提醒)

二、Django rest_Framework原理?

        先開始在路由,路由.as_view:

點擊as_view

           

請求進來,走完以上,才走self.dispatch()

self.dispatch()流程如下地址:http://www.cnblogs.com/mengqingjian/p/8419563.html 

三、版本

a.根據url的不同來來操作,版本控制

先在setting中註冊

 

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    #url(r'^admin/', admin.site.urls),
    url(r'^api/(?P<version>[v1|v2]+)/', include('api.urls')),
    # url(r'^api/', include('api.urls')),
    url(r'^backend/', include('backend.urls')),
]
url

 

REST_FRAMEWORK = {
    'VERSION_PARAM':'version',
    'DEFAULT_VERSION':'v1',
    'ALLOWED_VERSIONS':['v1','v2'],
    # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning"
    'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning"
}
settings.py配置
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BasicAuthentication
from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning,HostNameVersioning
from rest_framework.renderers import BrowsableAPIRenderer,JSONRenderer

class UsersView(APIView):
    # 基於url傳參
    # versioning_class = QueryParameterVersioning

    # 基於URL http://127.0.0.1:8001/api/v2/users/
    # versioning_class = URLPathVersioning

    # 基於子功能變數名稱 http://v1.luffy.com/users/
    # versioning_class = HostNameVersioning


    def get(self,request,*args,**kwargs):
        self.dispatch
        # print(request.version) # QueryParameterVersioning().detemiin_version()
        # print(request.versioning_scheme) # QueryParameterVersioning()

        # 當前版本一樣的URL
        # url = request.versioning_scheme.reverse(viewname='u',request=request)
        # print(url)

        # 當前版本不一樣的URL
        # from django.urls import reverse
        # url = reverse(viewname='u',kwargs={'version':'v2'})
        # print(url)


        return Response('...')
views.py
from django.conf.urls import url,include
from . import views
urlpatterns = [
    url(r'^users/', views.UsersView.as_view(),name='u'),
]
url.py -----和view在一個APP中的路由

b、

 HostName
            urlpatterns = [
                #url(r'^admin/', admin.site.urls),
                url(r'^api/', include('api.urls')),
            ]

            urlpatterns = [
                url(r'^users/', views.UsersView.as_view(),name='u'),
            ]
            
            
            class UsersView(APIView):
                
                def get(self,request,*args,**kwargs):
                    self.dispatch
                    print(request.version) # QueryParameterVersioning().detemiin_version()
                    print(request.versioning_scheme) # QueryParameterVersioning()

            
            REST_FRAMEWORK = {
                'VERSION_PARAM':'version',
                'DEFAULT_VERSION':'v1',
                'ALLOWED_VERSIONS':['v1','v2'],
                'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning"
            }
            
            # C:\Windows\System32\drivers\etc
            # vim /etc/hosts
            127.0.0.1    v1.luffy.com
            127.0.0.1    v2.luffy.com

四、rest framework解析器

請求的數據進行解析:請求體進行解析。表示服務端可以解析的數據格式的種類。

Content-Type: application/url-encoding.....
            request.body
            request.POST
            
            Content-Type: application/json.....
            request.body
            request.POST
        
        客戶端:
            Content-Type: application/json
            '{"name":"alex","age":123}'
        
        服務端接收:
            讀取客戶端發送的Content-Type的值 application/json
            
            parser_classes = [JSONParser,]
            media_type_list = ['application/json',]
        
            如果客戶端的Content-Type的值和 application/json 匹配:JSONParser處理數據
            如果客戶端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser處理數據
        
        
        配置:
            單視圖:
            class UsersView(APIView):
                parser_classes = [JSONParser,]
                
            全局配置:
                REST_FRAMEWORK = {
                    'VERSION_PARAM':'version',
                    'DEFAULT_VERSION':'v1',
                    'ALLOWED_VERSIONS':['v1','v2'],
                    # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning"
                    'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning",
                    'DEFAULT_PARSER_CLASSES':[
                        'rest_framework.parsers.JSONParser',
                        'rest_framework.parsers.FormParser',
                    ]
                }
from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    #url(r'^admin/', admin.site.urls),
    url(r'^api/(?P<version>[v1|v2]+)/', include('api.urls')),
    # url(r'^api/', include('api.urls')),
    url(r'^backend/', include('backend.urls')),
]
url.py
REST_FRAMEWORK = {
    'VERSION_PARAM':'version',
    'DEFAULT_VERSION':'v1',
    'ALLOWED_VERSIONS':['v1','v2'],
    # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning"
    'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning",
    'DEFAULT_PARSER_CLASSES':[
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
    ]
}
setting.py
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BasicAuthentication
from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning,HostNameVersioning
from rest_framework.renderers import BrowsableAPIRenderer,JSONRenderer
from rest_framework.parsers import JSONParser,FormParser
from rest_framework.request import Request
class UsersView(APIView):
    def get(self,request,*args,**kwargs):
        self.dispatch
        return Response('...')

    def post(self,request,*args,**kwargs):
        # # application/json
        # print(request._request.body) # b"xxxxx"   decode()   json.loads
        # print(request._request.POST) # 無
        #
        # # www-form-url-encode
        # print(request._request.body)
        # print(request._request.POST)
        # print(request.data)

        # print(request.POST)
        # print(request.FILES)

        request.data
        return Response('...')
views.py
from django.conf.urls import url,include
from . import views
urlpatterns = [
    url(r'^users/', views.UsersView.as_view(),name='u'),
]
url.py 和view一個APP下的文件

五、 rest framework序列化+Form

序列化:
        對象 -> 字元串 序列化
        字元串 -> 對象 反序列化
目的:
        解決QuerySet序列化問題

序列化:

a、基本操作

 

class UsersSerializer(serializers.Serializer):
                    name = serializers.CharField()
                    pwd = serializers.CharField()
            
                        
                class UsersView(APIView):
                    def get(self,request,*args,**kwargs):
                        self.dispatch
                        # 方式一:
                        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
                        # return Response(user_list)

                        # 方式二之多對象
                        # user_list = models.UserInfo.objects.all()
                        # ser = UsersSerializer(instance=user_list,many=True)
                        # return Response(ser.data)

                        # 方式二之單對象
                        user = models.UserInfo.objects.all().first()
                        ser = UsersSerializer(instance=user, many=False)
                        return Response(ser.data)

 

b、跨表

class UsersSerializer(serializers.Serializer):
                    name = serializers.CharField()
                    pwd = serializers.CharField()
                    group_id = serializers.CharField()
                    xxxx = serializers.CharField(source="group.title")
                    x1 = serializers.CharField(source="group.mu.name")



                class UsersView(APIView):
                    def get(self,request,*args,**kwargs):
                        self.dispatch
                        # 方式一:
                        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
                        # return Response(user_list)

                        # 方式二之多對象
                        user_list = models.UserInfo.objects.all()
                        ser = UsersSerializer(instance=user_list,many=True)
                        return Response(ser.data)

c、複雜序列化

解決方案一:
                    class MyCharField(serializers.CharField):

                        def to_representation(self, value):
                            data_list = []
                            for row in value:
                                data_list.append(row.name)
                            return data_list

                    class UsersSerializer(serializers.Serializer):
                        name = serializers.CharField() # obj.name
                        pwd = serializers.CharField()  # obj.pwd
                        group_id = serializers.CharField() # obj.group_id
                        xxxx = serializers.CharField(source="group.title") # obj.group.title
                        x1 = serializers.CharField(source="group.mu.name") # obj.mu.name
                        # x2 = serializers.CharField(source="roles.all") # obj.mu.name
                        x2 = MyCharField(source="roles.all") # obj.mu.name
    
                解決方案二:
                    class MyCharField(serializers.CharField):
                        def to_representation(self, value):
                            return {'id':value.pk, 'name':value.name}

                    class UsersSerializer(serializers.Serializer):
                        name = serializers.CharField() # obj.name
                        pwd = serializers.CharField()  # obj.pwd
                        group_id = serializers.CharField() # obj.group_id
                        xxxx = serializers.CharField(source="group.title") # obj.group.title
                        x1 = serializers.CharField(source="group.mu.name") # obj.mu.name
                        # x2 = serializers.CharField(source="roles.all") # obj.mu.name
                        x2 = serializers.ListField(child=MyCharField(),source="roles.all") # obj.mu.name

                解決方案三(*):
                    class UsersSerializer(serializers.Serializer):
                        name = serializers.CharField() # obj.name
                        pwd = serializers.CharField()  # obj.pwd
                        group_id = serializers.CharField() # obj.group_id
                        xxxx = serializers.CharField(source="group.title") # obj.group.title
                        x1 = serializers.CharField(source="group.mu.name") # obj.mu.name
                        # x2 = serializers.CharField(source="roles.all") # obj.mu.name
                        # x2 = serializers.ListField(child=MyCharField(),source="roles.all") # obj.mu.name
                        x2 = serializers.SerializerMethodField()

                        def get_x2(self,obj):
                            obj.roles.all()
                            role_list = obj.roles.filter(id__gt=1)
                            data_list = []
                            for row in role_list:
                                data_list.append({'pk':row.pk,'name':row.name})
                            return data_list

以上三種都是使用相同的視圖:

class UsersView(APIView):
                        def get(self,request,*args,**kwargs):
                            self.dispatch
                            # 方式一:
                            # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
                            # return Response(user_list)

                            # 方式二之多對象
                            user_list = models.UserInfo.objects.all()
                            # [obj1,obj2,obj3]
                            ser = UsersSerializer(instance=user_list,many=True)
                            return Response(ser.data)
d. 基於Model   
class UsersSerializer(serializers.ModelSerializer):
                    class Meta:
                        model = models.UserInfo
                        fields = "__all__"
                        # fields = ['name', 'pwd','group']
                        depth = 1


                class UsersView(APIView):
                    def get(self,request,*args,**kwargs):
                        self.dispatch
                        # 方式一:
                        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
                        # return Response(user_list)

                        # 方式二之多對象
                        user_list = models.UserInfo.objects.all()
                        # [obj1,obj2,obj3]
                        ser = UsersSerializer(instance=user_list,many=True)
                        return Response(ser.data)

e. 生成URL

class UsersSerializer(serializers.ModelSerializer):
                    group = serializers.HyperlinkedIdentityField(view_name='detail')
                    class Meta:
                        model = models.UserInfo
                        fields = "__all__"
                        fields = ['name', 'pwd','group']
                        depth = 1


                class UsersView(APIView):
                    def get(self,request,*args,**kwargs):
                        self.dispatch
                        # 方式一:
                        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
                        # return Response(user_list)

                        # 方式二之多對象
                        user_list = models.UserInfo.objects.all()
                        # [obj1,obj2,obj3]
                        ser = UsersSerializer(instance=user_list,many=True,context={'request':request})
                        return Response(ser.data)

f. 全局生成URL

class UsersSerializer(serializers.HyperlinkedModelSerializer):
                    class Meta:
                        model = models.UserInfo
                        fields = "__all__"

                        # fields = ['id','name','pwd']

                class UsersView(APIView):
                    def get(self,request,*args,**kwargs):
                        self.dispatch
                        # 方式一:
                        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
                        # return Response(user_list)

                        # 方式二之多對象
                        user_list = models.UserInfo.objects.all()
                        # [obj1,obj2,obj3]
                        ser = UsersSerializer(instance=user_list,many=True,context={'request':request})
                        return Response(ser.data)

請求數據驗證:

a、

 

class PasswordValidator(object):
                    def __init__(self, base):
                        self.base = base

                    def __call__(self, value):
                        if value != self.base:
                            message = '用戶輸入的值必須是 %s.' % self.base
                            raise serializers.ValidationError(message)

                    def set_context(self, serializer_field):
                        """
                        This hook is called by the serializer instance,
                        prior to the validation call being made.
                        """
                        # 執行驗證之前調用,serializer_fields是當前欄位對象
                        pass

                class UsersSerializer(serializers.Serializer):
                        name = serializers.CharField(min_length=6)
                        pwd = serializers.CharField(error_messages={'required': '密碼不能為空'}, validators=[PasswordValidator('666')])

 

b、

class PasswordValidator(object):
                    def __init__(self, base):
                        self.base = base

                    def __call__(self, value):
                        if value != self.base:
                            message = '用戶輸入的值必須是 %s.' % self.base
                            raise serializers.ValidationError(message)

                    def set_context(self, serializer_field):
                        """
                        This hook is called by the serializer instance,
                        prior to the validation call being made.
                        """
                        # 執行驗證之前調用,serializer_fields是當前欄位對象
                        pass

                class UsersSerializer(serializers.ModelSerializer):
                    class Meta:
                        model = models.UserInfo
                        fields = "__all__"
                        extra_kwargs = {
                            'name': {'min_length': 6},
                            'pwd': {'validators': [PasswordValidator(666), ]}
                        }

使用:

class UsersView(APIView):
                    def get(self,request,*args,**kwargs):
                        self.dispatch
                        # 方式一:
                        # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title")
                        # return Response(user_list)

                        # 方式二之多對象
                        user_list = models.UserInfo.objects.all()
                        # [obj1,obj2,obj3]
                        ser = UsersSerializer(instance=user_list,many=True,context={'request':request})
                        return Response(ser.data)

                    def post(self,request,*args,**kwargs):
                        ser = UsersSerializer(data=request.data)
                        if ser.is_valid():
                            print(ser.validated_data)
                        else:
                            print(ser.errors)
                        return Response('...')

 

 

 

 

 

 

 

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 題目背景 上道題中,妖夢斬了一地的木棒,現在她想要將木棒拼起來。 題目描述 有n根木棒,現在從中選4根,想要組成一個正三角形,問有幾種選法? 輸入輸出格式 輸入格式: 第一行一個整數n 第二行n個整數,a1,a2,……an(0<ai<=5000),代表每根木棒的長度。 輸出格式: 一行一個整數,對1 ...
  • 上一篇詳細介紹了與Servlet相關的幾個核心的介面和類,當我們自己寫Servlet類時,一般需要繼承HttpServlet類,實現init()、doGet()、doPost()等方法。當我們寫好Servlet類時,它在什麼時候被初始化(init())?什麼時候執行doGet()、doPost()等 ...
  • CSS佈局之圖像簽名 這是誰?————劉亦菲 ...
  • 共用記憶體 IPC 原理 共用記憶體進程間通信機制主要用於實現進程間大量的數據傳輸,下圖所示為進程間使用共用記憶體實現大量數據傳輸的示意圖: 共用記憶體是在記憶體中單獨開闢的一段記憶體空間,這段記憶體空間有自己特有的數據結構,包括訪問許可權、大小和最近訪問的時間等。該數據結構定義如下: ~~~~ from /usr ...
  • 在上一篇文章對Java做了一個簡單介紹之後,我想大家都已經對她有一個初步的認識了吧!那踏入正式學習使用Java之前,我們有一步是不得不做的,它是什麼呢?沒有錯,就是我們本篇文章的標題所說,搭建Java的開發環境。那我們就正式進入主題吧! 因為Java現在對主流的平臺幾乎都支持,環境搭建也是大同小異, ...
  • eg:計算10002-99的差 ① ...
  • 效果: ...
  • 今天調試db2數據的存儲時,jdbc使用addBatch方法時,拋出異常,異常信息如下: [jcc][1091][10404][3.62.56] 數據轉換無效:參數實例 對於所請求的轉換無效。 ERRORCODE=-4461, SQLSTATE=42815 db2 顯示 SQLSTATE 42815 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...