drf從入門到精通---day05

来源:https://www.cnblogs.com/tengyifan888/archive/2023/02/05/17089287.html
-Advertisement-
Play Games

今日內容概要 昨日回顧 反序列化類校驗部分源碼解析(瞭解) 斷言 drf之請求(配置解析類) drf之響應(配置響應類,Resposne的源碼的屬性) 視圖組件介紹及兩個視圖基類與五個視圖擴展類的用法介紹 . . . . 昨日回顧 # 1 序列化類的常用欄位 -CharField 。。。。 -Lis ...


今日內容概要

  • 昨日回顧
  • 反序列化類校驗部分源碼解析(瞭解)
  • 斷言
  • drf之請求(配置解析類)
  • drf之響應(配置響應類,Resposne的源碼的屬性)
  • 視圖組件介紹及兩個視圖基類與五個視圖擴展類的用法介紹
    .
    .
    .
    .

昨日回顧

# 1 序列化類的常用欄位
    -CharField
    。。。。
    -ListField
    -DictField
-------------------------------

# 2 欄位參數
    -max_length。。。
    -min_value。。。
    -required,default。。。
    -read_only,write_only
-------------------------------

# 3 定製序列化欄位(改名字)
    -source這個欄位參數
    -如果是表模型自己的欄位,直接寫
    -如果是關聯表欄位,通過外鍵.的方式 拿到
-------------------------------

# 4 定製序列化欄位(格式更豐富)
     -在序列化類中使用:SerializerMethodField,配合一個 get_欄位名的方法,方法返回什麼,這個欄位就是什麼----》這種欄位以後不能用來,做反序列化了!!!
    -在表模型中使用,寫方法的方式,方法返回什麼,這個欄位前端顯示的就是啥,序列化類中需要配合ListField,DictField----》這種欄位以後不能用來,做反序列化了!!!
    -方法可以包裝成數據屬性加@property,也可以不加@property
-------------------------------

# 5 反序列化校驗幾層
    -1 欄位自己的校驗規則:序列化類欄位參數控制的
    -2 每個欄位單獨設置校驗方法(瞭解)
    -3 局部鉤子
    -4 全局鉤子

ser調用is_valid方法的時候,就會將4層校驗從上往下依次執行
ser調用save方法,觸發的是create或者update方法的執行!!
-------------------------------

# 6 ModelSerializer:繼承自Serializer
    class BookSerializer(ModelSerializer):
        # 如果欄位是映射過來的,也會把欄位屬性[反序列化校驗規則],也會映射過來,有可能會校驗失敗,不能寫入
        # 咱們重寫這個欄位,不加任何規則,取消掉它
        name = serializer.CharField()
        class Meta:
            model=Author
            # fields="__all__"
            # 只要是序列化的欄位和反序列化的任何欄位,都要在這註冊
            # 序列化的欄位,可能不是表模型的欄位,是在表模型中寫的方法名
# 序列化的欄位,也可能是在序列化類裡面的,寫的定製化欄位,SerializerMethodField,也要註冊
            fields=['name','photo','gender','addr']
            extra_kwargs={'name':{'max_length': 8}}  # 給欄位類增加屬性,read_only 和write_only用的多

        gender=serializer.CharField()
        addr=serializer.CharField()

        # 局部鉤子,全局鉤子 和原來的用法完全一樣
        # 在序列化類裡面寫定製化欄位方法的SerializerMethodField的用法和 原來也一樣

        def create(self, validated_data):
            pass
        def update(self, instance, validated_data):
            pass

-------------------------------

# 7 反序列化的欄位,一定跟表模型的欄位是對應的嗎?  不一定,隨意寫。
# 因為反序列化的欄位,可能是要存到兩張表裡面去的。
註意因為現在BookSerializer類繼承了ModelSerializer,
前端提交過來的數據包含了兩個表裡面的數據,但是序列化類只和Book模型表建立了關聯
只要反序列化,就必須要在fields裡面註冊一下。

但是在將book表裡面的欄位映射的序列化表裡面的時候,是不可能將另一個表裡面的欄位也映射過來的。

所以需要在序列化表裡面,把該欄位重寫一下就行了,如果需要欄位校驗也一樣在括弧裡面寫欄位的校驗參數,如果需要其他的邏輯校驗,就寫鉤子函數。

最後我們需要在序列化類裡面要重寫create方法,因為ModelSerializer封裝了create方法,但是該方法只能適用於前端傳的是關聯表裡面的欄位數據,會自動將前端的數據利用ORM寫到資料庫裡面去。

但是現在前端傳的是兩個表裡面的數據,所以我們要重寫create方法,自己將兩個表裡面的數據從validated_data裡面拿出來,利用ORM分別寫到兩張表裡面去!!!!!!

image
.
.
.
.
.

1 反序列化類校驗部分源碼解析(瞭解)


反序列化校驗,什麼時候開始執行校驗?
視圖類中的調用 ser.is_valid(), 就會執行校驗,校驗通過返回True,不通過返回False

----------------------------------------
ser是我們自己寫的BookSerializer序列化類的對象
入口:ser.is_valid() ------BookSerializer類裡面沒有is_valid------繼續找最終找到了父類-----BaseSerializer中的is_valid

註意視圖類post函數裡面 if ser.is_valid():  括弧裡面寫raise_exception=True,就會直接拋異常!!
-----------------------------------------
-----------------------------------------
   def is_valid(self, *, raise_exception=False):

        if not hasattr(self, '_validated_data'):
            try:
            # self序列化類的對象,屬性中沒有_validated_data,一定會走下麵這句【核心】
    # 這句走完後,對象就有該屬性了,下次對象再點is_valid方法時,下麵這句話肯定就不走了
 # 所以is_valid被對象調用一次,與被對象調用多次的效果是一樣的!,只有第一次的時候會校驗
                self._validated_data = self.run_validation(self.initial_data)
            except ValidationError as exc:
                self._validated_data = {}
                self._errors = exc.detail
            else:
                self._errors = {}

        if self._errors and raise_exception:
            raise ValidationError(self.errors)

        return not bool(self._errors)
-----------------------------------------
-----------------------------------------
# self._validated_data = self.run_validation(self.initial_data)  這行代碼的self是序列化類的對象

-切記一定不要按住ctrl鍵點擊名字,因為系統預設是基於當前名字所屬的類查找及往上找!!
-哪個對象調用的該方法,那麼該方法裡面self就是哪個對象,和self當前所在的函數所屬的類無關!!!
-所以真正的查找順序是,從self所指代的這個對象開始從下往上找,找不到,再往上,知道找到該方法!!!
-最終從Serializer類中找到了run_validation,而不是Field中的run_validation !!
-----------------------------------------
-----------------------------------------

    def run_validation(self, data=empty):
        # 執行欄位自己的,及validates方法,也就是第一層與第二層的校驗
        (is_empty_value, data) = self.validate_empty_values(data)
        if is_empty_value:
            return data

        # 局部鉤子----【局部鉤子】
        value = self.to_internal_value(data)

        try:
            self.run_validators(value)

        # 全局鉤子--》如果在BookSerializer中寫了全局鉤子validate,優先走它,非常簡單
            value = self.validate(value)

        except (ValidationError, DjangoValidationError) as exc:
            raise ValidationError(detail=as_serializer_error(exc))
        return value

-----------------------------------------
-----------------------------------------

# 局部鉤子  self.to_internal_value(data) ---》self是BookSerializer的對象,從根上找
# 最後在Serializer類中找到了

     def to_internal_value(self, data):
        ret = OrderedDict()
        errors = OrderedDict()
        fields = self._writable_fields
        # fields 就是寫在序列化類中一個個欄位類的對象!!!
        for field in fields:
            # self 是BookSerializer的對象
            # 還是用反射,反射出BookSerializer對象中的局部鉤子函數的函數名字
            validate_method = getattr(self, 'validate_' + field.field_name, None)
            try:
               # 執行BookSerializer類中的鉤子函數方法,傳入了要校驗的數據
                validated_value = validate_method(validated_value)
            except ValidationError as exc:
                errors[field.field_name] = exc.detail

            else:
                set_value(ret, field.source_attrs, validated_value)

        if errors:
            raise ValidationError(errors)

        return ret

image
.
.
.
.

2 斷言

# 源碼中大量使用try和斷言
#  關鍵字assert ,有什麼作用,斷定你是什麼,如果是沒事,如果不是就拋異常
--------------------------------------------
name = 'zzz'

if name == 'lqz':
     pass
else:
     raise Exception('名字不為lqz,不能繼續走了')
print('後續代碼')
---------------------
上面代碼可以寫成這樣
name = 'zzz'
assert name=='lqz'   # 斷定是,沒問題,代碼繼續往下走,如果不是,就主動拋異常!!
print('後續代碼')

----------------------------------------------
    def is_valid(self, *, raise_exception=False):
    # 斷言對象裡面有'initial_data'屬性,如果有就繼續往下走,如果沒有就主動拋異常報錯了
        assert hasattr(self, 'initial_data')

        if not hasattr(self, '_validated_data'):
            try:
                self._validated_data = self.run_validation(self.initial_data)
            except ValidationError as exc:
                self._validated_data = {}
                self._errors = exc.detail
            else:
                self._errors = {}

# 判斷後面的代碼的結果的布爾值,True就正常繼續往下走,False就主動拋異常,不讓代碼往下走了!!!  斷言的主要目的就是如果是False,不讓代碼往下走了
--------------------------------------------------

.
.
.
.

3 drf之請求

3.1 Request能夠解析的前端傳入的編碼格式-------配置解析類

# 需求是該介面只能接收某種編碼格式,比如json格式,不能接收其他格式
---------------------------------------------

方式一,在繼承自APIView及其子類的的視圖類中配置(局部配置,只對該視圖類有效)
# 總共有三個:
from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
class BookView(APIView):
    parser_classes = [JSONParser,]

# 這樣一配置,以後該視圖類只能夠解析,用json格式編碼傳入的文件了!!用其他格式編碼傳入的文件就解析不了了!!!

# parser_classes 解析類 意思是能夠解析前端傳入的上面編碼格式(預設情況下配了3個解析類)
# drf解析類已經幫我們寫好了,我們只需要導入即可!
----------------------------------------------

方式二:在配置文件中配置(影響所有,全局配置)

-django有套預設配置,每個項目也有個配置
-drf也有套預設配置,每個項目也有個配置(就是django的配置文件)
------------------

    REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        # 'rest_framework.parsers.FormParser',
        # 'rest_framework.parsers.MultiPartParser',
    ],
}

# 這樣在django的配置文件中寫一下,假如上面的視圖類裡面不配置解析類,在這裡配置的就對整個django項目生效了!!!
------------------------------------------------

方式三:全局配了1個解析類,某個視圖類想要配3個解析類,怎麼配?

-只需要在視圖類,配置3個即可
-因為:先從視圖類自身找,找不到,再去項目的drf配置(django項目配置)中找,再找不到,去drf預設的配置找

如果是json格式編碼,request.data就是普通dict
image
.
如果urlencoded,或form-data編碼,就是querydict
image
.
.
DRF的配置文件查找
lib---site-packges---rest-framework---settings.py文件裡面
image
.
image
.
.
這樣在django的配置文件中寫一下,在這裡配置的就對整個django項目生效了!!!
image
.
.
.

3.2 Request類有哪些屬性和方法(學過)

# 視圖類方法中的request
data
__getattr__
query_params

.
.
.

4 drf之響應

4.1 Response能夠響應的編碼格式-------配置響應類

drf  是djagno的一個app,所以要註冊!!!
drf的響應,如果使用瀏覽器和postman訪問同一個介面,返回格式是不一樣的
drf做了個判斷,如果是瀏覽器,好看一些,如果是postman只要核心的json數據
------------------------------------------
------------------------------------------
# 需求:現在想讓瀏覽器也返回的也像postman一樣,就返回核心的json數據,怎麼辦?
# 兩個響應類------drf的預設配置文件中找------兩個類

方式一:在視圖類中寫(局部配置,只對視圖類有效)

from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer

class BookView(APIView):
    renderer_classes=[JSONRenderer,]

----------------------------------------------

方式二:在項目配置文件中寫(全局配置,整個項目有效)

REST_FRAMEWORK = {
      'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],
}

------------------------------------------

方式三:使用順序(一般就用內置的即可)
	優先使用視圖類中的配置,其次使用項目配置文件中的配置,最後使用內置的

drf 是djagno的一個app,所以要註冊!!!
image
.
.
.
.

4.2 Resposne的源碼屬性或方法

# drf 的Response 源碼分析
from rest_framework.response import Response
視圖類的方法返回時,retrun Response ,走它的 __init__
研究 init中可以傳什麼參數
------------------------------------------

# Response init 可以傳的參數

    def __init__(self,
                 data=None,
                 status=None,
                 template_name=None,
                 headers=None,
                 exception=False,
                 content_type=None)

# data:之前咱們寫的ser.data  可以是字典或列表或字元串---》序列化後返回給前端---》前端在響應體中看到的就是這個

# status:http響應的狀態碼,預設是200,你可以改。
drf在status包下,把所有http響應狀態碼都寫了一遍,是個常量
from rest_framework.status import HTTP_200_OK
Response('dddd',status=status.HTTP_200_OK)
Response('dddd',status=200)  # 這兩句話一個意思

# template_name:瞭解即可,修改響應模板的樣子,BrowsableAPIRenderer定死的樣子,後期公司可以自己定製

# headers:響應頭,http響應的響應頭,可以通過傳參的形式headers={'name': 'lqz'} 往響應頭裡面塞東西!!!
思考,原生djagno如何用4板斧向響應頭中加東西 ?
    # 四件套 render,redirect,HttpResponse,JsonResponse
    obj = HttpResponse('dddd')
    obj['age'] = '18'
    obj['name'] = 'lqz'
    return obj

# content_type :響應編碼格式,一般不動
-----------------------------------------------
# 重點:data,status,headers

from rest_framework.status import HTTP_200_OK
image
.
用DRF的Response 往響應頭裡面加東西
image
image
.
用django的四板斧 往響應頭裡面加東西
image
image
.
.
.
.

5 視圖組件介紹 及 兩個視圖基類 與 五個視圖擴展類的 用法介紹

# 之前學過APIView,是drf的基類,是drf提供的最頂層的類
------------------------------------------
# APIView跟之前的View區別:
-傳入到視圖方法中的是REST framework的Request對象,而不是Django的HttpRequeset對象
-視圖方法可以返回 REST framework的Response對象
-任何APIException異常都會被捕獲到,並且處理成合適的響應信息
-在進行dispatch()分發前,會對請求進行身份認證、許可權檢查、頻率流量控制

------------------------------------------

# drf的 兩個視圖基類
APIVIew  與  GenericAPIView
------------------------------------------

# APIVIew的類裡面屬性:
	renderer_classes  # 響應格式類
	parser_classes  # 能夠解析的請求格式類
	authentication_classes  # 認證類
	throttle_classes  # 頻率類
	permission_classes  # 許可權類

.
.
.
.

5.1 第一層 用APIView + ModelSerializer + Resposne 寫5個介面

# 視圖類代碼
from .models import Book
from .serializer import BookSerializer


class BookView(APIView):
    def get(self, request):
        books = Book.objects.all()
        ser = BookSerializer(instance=books, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '新增成功', 'result': ser.data})
# restful規範裡面要求把新增對策數據返回,怎麼返回新增的數據 ?
# 我們現在只有ser序列化類的對象,能不能拿到新增的對象?可以,ser.save方法運行會觸發create方法運行,create方法的返回值就是新增的對象
# 所以ser.data該方法的作用:就是將create方法的返回值也就是新增的表模型對象,再序列化成字典給前端
# 所以說雖然post方法整體是將前端的字元串轉化為對象的反序列化的過程,但是該方法最後還是有一步將對象序列化成字典的過程!!
# 所以序列化類中的create方法一定要返回新增的對象,否則ser.data方法沒拿到新增的對象,序列化也拿不到新增對象的數據!!!

        else:
            return Response({'code': 101, 'msg': ser.errors})


class BookDetailView(APIView):
    def get(self, request, pk):
        books = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=books)
# 所以說ser=BookSerializer(XXX)只是一個生成對象給對象添加屬性的過程,正真將表模型對象轉成字典是ser.data在做!!!
        return Response(ser.data)


    def put(self, request, pk):
        books = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=books, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '修改成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '刪除成功'})

-----------------------------------------------
-----------------------------------------------
-----------------------------------------------
# 序列化類
### ModelSerializer的使用
class BookSerializer(serializers.ModelSerializer):
    # 跟表有關聯
    class Meta:
        model = Book
        fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors']
        extra_kwargs = {'name': {'max_length': 8},
                        'publish_detail': {'read_only': True},
                        'author_list': {'read_only': True},
                        'publish': {'write_only': True},
                        'authors': {'write_only': True},
                        }

# ModelSerializer序列化類幫我們幹了好多事,原來用Serializer序列化類時,序列化欄位與反序列化欄位都要我們自己寫,現在用fields配一下,全部將模型表裡面的欄位都映射過來了
# 而且最騷的是模型表裡面的一對多的外鍵欄位映射過來自動變成了Integerfield,多對多的外鍵欄位映射過來自動變成了ListField的了!!
# 而且原來我們要自己寫create與update方法,將校驗過後的數據利用ORM語句寫入資料庫,現在全被ModelSerializer序列化類自動幫我們幹了!!!
-----------------------------------------------
-----------------------------------------------
-----------------------------------------------
# 路由
urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>/', views.BookDetailView.as_view()),
]

.

註意前端傳數據反序列新增或者修改的時候,用postman在請求體裡面寫數據的時候有點不一樣
比如json格式我們這樣寫
{"name":"紅樓","price":199,"publish":1,"authors":[1,3]}
但是如果用urlencode或者form-data格式寫的時候,對於多對多的authors外鍵欄位有點不一樣,
authors鍵對應的框裡面不能直接填一個[1,3],而是要把authors寫兩遍,一個對應1,一個對應3
這麼來操作

image
.
.
.
.

5.2 第二層 基於 GenericAPIView + ModelSerializer 寫5個介面

# 研究 如果我們要寫publish的5個介面,只要複製之前的代碼,改一部分,就可以快速寫出publish的5個介面,區別就只在於表模型與序列化類

# 可以通過繼承,少些代碼,GenericAPIView 繼承了APIView 並擴展了新的屬性與方法!!
'''
GenericAPIView 的屬性和方法:
屬性:
queryset: 要序列化或反序列化的表模型對象
serializer_class: 使用的序列化類
lookup_field : 查詢單條的 路由匹配的轉換器裡面的分組名
filter_backends: 過濾類的配置
pagination_class: 分頁類的配置

方法:
get_queryset()  獲取序列化的對象
get_object()    獲取單個對象
get_serializer()  獲取序列化對象
filter_queryset()  跟後續的排序由關係
'''

from rest_framework.generics import GenericAPIView


class BookView(GenericAPIView):
    queryset = Book.objects.all()
    # 原來我們是寫在函數裡面的,現在寫外面,在函數裡面通過self.queryset拿表模型對象

    serializer_class = BookSerializer

    def get(self, request):
        # objs = self.queryset
        # 這裡可以拿到,但是不要這麼用,GenericAPIView提供了另一個方法

        objs = self.get_queryset()
        # get_queryset()函數的返回值就是self.queryset,相當於套了一層殼
        # 那不是多此一舉嗎?那你就淺了,這樣操作有個好處,可以在序列化類裡面重寫該get_queryset方法
        # 然後在self.queryset裡面加點其他數據,或者剔除掉一些數據,那序列化的對象是不是就不一樣了!所以直接拿就寫死了,擴展性差了!!
        # 調用get_queryset()前,就可以在拿前先重寫get_queryset()方法,對queryset對象先處理一下!!!

        ser = self.get_serializer(instance=objs, many=True)
        # 同理也是給self.serializer_class() 套了一層殼!!後期可以重寫get_serializer_class方法,通過返回值來控制所使用的序列化類
        return Response(ser.data)


    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '新增成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})


class BookDetailView(GenericAPIView):
    queryset = Book.objects.all()  # 原來我們是寫在函數裡面的,現在寫外面,在函數裡面通過self.queryset拿表模型對象
    serializer_class = BookSerializer
    # lookup_field = 'pk'  # 如果路由匹配的轉換器裡面的分組名不是pk,要手動在這改一下,如果是pk這句話可以不寫!

    def get(self, request, pk):
        obj = self.get_object()  # 獲取表模型的單條對象
        ser = self.get_serializer(instance=obj)
        return Response(ser.data)

    def put(self, request, pk):
        obj = self.get_object()
        ser = self.get_serializer(instance=obj, data=request.data)

        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '修改成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, request, pk):
        self.get_object().delete()
        return Response({'code': 100, 'msg': '刪除成功'})

.
.
.
.
.

5.3 第三層 基於 5個視圖擴展類 + ModelSerializer 寫5個介面

# 視圖類代碼

from rest_framework.mixins import CreateModelMixin, UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin, ListModelMixin

# 基於GenericAPIView + 5個視圖擴展類寫介面

class BookView(GenericAPIView, ListModelMixin, CreateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)


class BookDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

  # def get(self, request, pk):
      # return self.retrieve(request,pk)     可以直接寫pk 也可以像下麵一樣寫,都行

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

-----------------------------------------------
-----------------------------------------------
-----------------------------------------------
# 序列化類代碼

class BookSerializer(serializers.ModelSerializer):
    # 跟表有關聯
    class Meta:
        model = Book
        fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors']
        extra_kwargs = {'name': {'max_length': 8},
                        'publish_detail': {'read_only': True},
                        'author_list': {'read_only': True},
                        'publish': {'write_only': True},
                        'authors': {'write_only': True},
                        }
-----------------------------------------------
-----------------------------------------------
-----------------------------------------------
# 路由

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>/', views.BookDetailView.as_view()),
]

.
.
.
.

作業

# 1 研究反序列化源碼
# 2 整理斷言的使用
# 3 整理drf的請求與響應

# 4 基於APIView寫5個介面
	基於GenericAPIView
    基於GenericAPIView+5個視圖擴展類

# 5 剩下兩層
	-第一層
    class PublishView(CreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    class BookDetailView(DestroyAPIView):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
        
    -第二層帶5個介面
      class PublishView(CreateAPIView):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
    	

# 周六周天:刷 面向對象視頻

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

-Advertisement-
Play Games
更多相關文章
  • 一、RabbitMQ是什麼 RabbitMQ是一種常用的消息中間件,是基於AMQP協議,採用erlang語言開發的面向消息服務的中間件,是一個獨立的系統應用程式,可以管理伺服器計算資源和網路通信。一般可作為同構或異構系統間的數據交換平臺,由於erlang語言的高併發特性,使得RabbitMQ的性能較 ...
  • ​ ​編輯 列表和元組 list 是一種有序、可變的數據類型,可添加刪除其中的元素。 len()函數:可以獲取列表元素的個數 classmates = ['Micheal' , 'Bob' , 'James'] print(classmates) print(len(classmates)) Ter ...
  • 突發奇想,爬取p站圖片做個壁紙圖庫(bukemiaoshu),當然這裡有許多的門檻,但是為了實現理想,暫時沒想那麼多了,直接開乾(不是專業做測試和自動化的,如有大佬請評論指教!!!) 1.進入登錄頁由於p站是需要登錄的,聽說p站反爬,requests應該不是那麼好使,於是使用selenium模擬人工 ...
  • 這篇文章主要描述分散式系統的發展歷程和分散式系統的衡量指標。發展歷程包括了單機模式、數據並行模式和任務並行模式。分散式系統的衡量指標包括性能、資源占用、可用性和可擴展性。 ...
  • Java JDK1.5: 泛型 新特性的講解說明 每博一文案 聽到過這樣一句話:“三觀沒有標準。在烏鴉的世界里,天鵝也有罪。” 環境、閱歷的不同,造就了每個人獨有的世界觀、人生觀、價值觀。 三觀並無對錯高下,只有同與不同。恰如飛鳥不用和游魚同行,高山不必同流水相逢。 總用自己的尺子去度量別人,無疑是 ...
  • Elasticsearch是位於 Elastic Stack 核心的分散式搜索和分析引擎。Elasticsearch 是索引、搜索和分析魔法發生的地方。lasticsearch 為所有類型的數據提供近乎實時的搜索和分析。無論您擁有結構化或非結構化文本、數字數據還是地理空間數據,Elasticsear... ...
  • 簡介 前幾天搗鼓了一下Ubuntu,正是想用一下我舊電腦上的N卡,可以用GPU來跑代碼,體驗一下多核的快樂。 還好我這破電腦也是支持Cuda的: $ sudo lshw -C display *-display description: 3D controller product: GK208M [ ...
  • https://www.cnblogs.com/yeungchie/ 函數功能 Perl 中 shift 函數可以返回列表的第一個元素,並將後續所有元素向前移位( 索引值減 1 )。輸入可選,預設為 @_ 或者 @ARGV。 my @foo = qw( 1 2 3 4 ); say shift @f ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...