<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      TOP

      DRF 基本功能梳理 demo

      模型類

      from django.db import models
      
      
      # Create your models here.
      
      class Book(models.Model):
          title = models.CharField(max_length=50, verbose_name="標題", help_text="標題")  # help_text : 文檔的顯示信息
          collect_num = models.IntegerField(default=0, verbose_name="收藏數", help_text="收藏數")
          author = models.ForeignKey('Author', on_delete=models.CASCADE, related_name='books', help_text="作者")
      
          def __str__(self):
              return self.title
      
      
      class Author(models.Model):
          name = models.CharField(max_length=30, verbose_name="姓名", help_text="姓名")
          age = models.IntegerField(default=18, verbose_name="年齡", help_text="年齡")
          publish = models.ManyToManyField('Publish', help_text="出版社")
      
          def __str__(self):
              return self.name
      
      
      class Publish(models.Model):
          name = models.CharField(max_length=30, verbose_name="出版社名", help_text="出版社名")
          create_dt = models.DateField(verbose_name="成立時間", default="1995-06-01", help_text="成立時間")
      
          def __str__(self):
              return self.name

      模型類拓展字段

      在模型類中中可以以  property  修飾方法為類變量, 然后即可在序列化器中作為邏輯數據庫字段使用

      通常可以進行系列數據的拓展屬性展示, 但是此字段不可帶有任何參數裝飾器本身就是去除到 () 執行, 因此參數是無從傳遞

      倘若需要從request 傳遞的動態參數, 則只能在 序列化器中操作

      class XXX(models.Model):
        .....
        .....
      @property def xxx(self): if self.x1: return { "x2": self.x2, "x3": self.x3, } return { "x2": None, "x3": None } class Meta: verbose_name = "某某模型" verbose_name_plural = verbose_name

       

      序列化類

      from rest_framework import serializers
      from .models import Book, Author, Publish
      
      
      
      # 自定義校驗方法
      def check_name(value):
          if "羊駝" not in value:
              raise serializers.ValidationError("必須要有羊駝")
      
          return value
      
      
      class AuthorSerializer(serializers.ModelSerializer):
          # 常規方式對字段進行校驗, 將 model 的字段在這里重復寫一遍
          name = serializers.CharField(max_length=30, label="姓名", validators=[check_name])  # validators 自定義校驗方法
         """Meta 相關屬性"""
          class Meta:
              model = Author
              # fields = ["id", "name"] # 自己指定要序列化的字段
              """
              fields 和 exclude 不能同時存在
              Cannot set both 'fields' and 'exclude' options on serializer AuthorSerializer.
              這兩個字段的源碼位置 ModelSerializer.get_field_names
              
              # exclude = ["id"]  # 排除某些字段
              """
              # 生成指定字段
              fields = "__all__"  # 所有的字段都加進來
              # 設置只讀字段
              read_only_fields = []  # 源碼位置 ModelSerializer.get_extra_kwargs
              # 給字段添加額外約束
              extra_kwargs = {  # # 源碼位置 ModelSerializer.get_extra_kwargs
                  "name": {
                      "max_length": 30,
                      "min_length": 1,
                  }
      
              }
      
          """多對一的復寫"""
          # 多對一的地方需要使用反向字段 如果未設置則為 關聯對象表名+ _set 如果設置了 related_name, 則直接使用 related_name
          # 多的一方無法自定義字段國擴展
          # books = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
          # 使用 關聯對象的  __str__ 方法作為填充
          books = serializers.StringRelatedField(read_only=True, many=True)
      
      
      class BookSerializer(serializers.ModelSerializer):
          class Meta:
              model = Book
              fields = "__all__"
      
          """一對多字段的復寫, 若不復寫取出的是 id (int) """""
          # 0. 默認的外鍵字段序列化方式, 取出的是 關聯對象的 ID/ PK
          # author = serializers.PrimaryKeyRelatedField(read_only=True)
          # 1. source 對序列化方式進行復寫
          author_id = serializers.CharField(source="author.id", read_only=True)  # str(obj.publish.id) 取 pk 也是一樣
          # 2. 可實現自定義拓展字段, 一對多 在 "一" 的一方可以使用, 在 "多" 的一方不可使用
          author_name = serializers.CharField(source="author.name", read_only=True)
          # 3. 返回 關聯對象的 __str__ 方法 - 必須基于已有的字段
          # author = serializers.StringRelatedField(read_only=True)
          # 4. 使用序列化器作為關聯 - 必須基于已有的字段
          author = AuthorSerializer(read_only=True)  # 取出所有的子字段
      
          """
          單字段校驗 - 實現對字段的額外要求的校驗
          固定格式: validate(可自動提示) + _ + 校驗字段名
          自定義邏輯在主校驗邏輯之后, 相當于額外校驗, 而非完全替換校驗
          """""
      
          @staticmethod
          def validate_title(value):
              """自定義邏輯"""
              if "羊駝" not in value:
                  # return False # return 不管是什么都是通過
                  # 必須拋出異常才可以表示校驗不通過
                  """
                  HTTP 400 Bad Request
                  Allow: GET, POST, HEAD, OPTIONS
                  Content-Type: application/json
                  Vary: Accept
      
                  {
                      "title": [
                          "不贊美羊駝不通過"
                      ]
                  }
                  """
                  raise serializers.ValidationError("不贊美羊駝不通過")
      
              return value  # 通過返回 value 即可
      
          """
          多字段校驗 - 實現對字段的額外要求的校驗
          validate
          自定義邏輯在主校驗邏輯之后, 相當于額外校驗, 而非完全替換校驗
          """""
      
          def validate(self, attrs):
              """
              bs = BookSerializer(data=request.data)
              attrs: 就是外界穿過來的數據  request.data
              
              多字段的校驗里面也可以對單字段分別校驗
              """""
              # 自定義邏輯
              title = attrs["title"]
              collect_num = attrs["collect_num"]
              if str(collect_num) not in title:
                  """
                  HTTP 400 Bad Request
                  Allow: GET, POST, HEAD, OPTIONS
                  Content-Type: application/json
                  Vary: Accept
                  
                  {
                      "non_field_errors": [
                          "書名里面要有收藏數里面的數字"
                      ]
                  }
                  """
                  raise serializers.ValidationError("書名里面要有收藏數里面的數字")
      
              return attrs  # 校驗通過返回原參數
      
          """
          數據入庫 - 創建 create
          數據入庫 - 更新 update
          
          """
      
          def create(self, validated_data):
              """
      
              :param validated_data:  校驗后的數據
              :return:
              """
              book = Book.objects.create(**validated_data)
      
              return book
      
          def update(self, instance, validated_data):
              """
      
              :param instance: 待更新的對象
              :param validated_data: 校驗后的數據
              :return:
              """
              instance.title = validated_data["title"]
              instance.collect_num = validated_data["collect_num"]
              instance.save()
              return instance
      
      
      class PublishSerializer(serializers.ModelSerializer):
          class Meta:
              model = Publish
              fields = "__all__"

      序列化中拓展字段

      部分場景可能存在需要動態參數, 即從request 中的數據作為參數對某些字段控制

      如以下場景. 在訂單序列化器中加入 is_flavor 字段用于標識當前用戶對此訂單是否已收藏

      在序列化中,  self 的 context 上下文會存儲 request , 從而實現此操作

      # 工單列表序列化器
      class OrderListModelSerializer(serializers.ModelSerializer):
          is_flavor = serializers.SerializerMethodField()
      
          def get_is_flavor(self, obj):
              user = self.context['request'].user
              return obj.is_flavor(user.u_name or user.username)
      
          class Meta:
              model = models.Order
              fields = (
              ....."is_flavor",
              .....
              )

       

      路由

      主路由

      """untitled1 URL Configuration
      
      The `urlpatterns` list routes URLs to views. For more information please see:
          https://docs.djangoproject.com/en/2.2/topics/http/urls/
      Examples:
      Function views
          1. Add an import:  from my_app import views
          2. Add a URL to urlpatterns:  path('', views.home, name='home')
      Class-based views
          1. Add an import:  from other_app.views import Home
          2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
      Including another URLconf
          1. Import the include() function: from django.urls import include, path
          2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
      """
      from django.contrib import admin
      from django.urls import path, include
      from rest_framework.documentation import include_docs_urls
      
      urlpatterns = [
          path('admin/', admin.site.urls),
          path('yangtuo/', include('yangtuo.urls')),
          path('docs/', include_docs_urls(title='yangtuo API')),
      ]

      子路由

      from rest_framework import routers
      from .views import BooksView, AuthorsView, PublishesView
      from django.urls import path
      
      routers = routers.DefaultRouter()
      routers.register('books', viewset=BooksView)
      routers.register('author', viewset=AuthorsView)
      routers.register('publish', viewset=PublishesView)
      #action 裝飾器替換
      """
      # 自定義路由
      path("publish/get_yangtuo_publish/", PublishesView.as_view({"get": "get_yangtuo_publish"})),
      # 自定義部分更新路由
      path("publish/change_publish/<int:pk>/", PublishesView.as_view({"put": "change_publish"}))
      """
      urlpatterns = [
      
      ]
      urlpatterns += routers.urls
      print(urlpatterns)

      過濾器

      詳細的文檔這里 這里這里

      常用過濾器

         CharFilter  字符串過濾器  

         DateTimeFilter  時間過濾器

         BooleanFilter   布爾過濾器

         NumberFilter  數字過濾器

         DateRangeFilter  時間范圍過濾器

      內部屬性

          field_name  查詢字段

          lookup_expr  匹配模式(與orm 的運算符一致)

          label  顯示字段 (用于 drf 渲染器中的字段)

          method  指定函數

      指定函數的時候必須傳遞 三個固定參數 

         queryset  在視圖中的 get_queryset 函數的返回結果

         name 

         value  request 指定過濾參數傳遞的值

      meta 字段

         model  指定模型, 類, 不是字符串

         fields  過濾參數, 不加入這里, 上面定義了也是可以使用的. 此處是用于指定數據庫字段所用

         exclude  排除字段, 不能用作過濾的參數

      示例

      class OrderFilter(django_filters.rest_framework.FilterSet):
          i_followers = django_filters.CharFilter(field_name='followers', lookup_expr='icontains', label="關注人(包含)")
          start_date = django_filters.rest_framework.DateTimeFilter(field_name='create_time', lookup_expr='gte',
                                                                    label="開始時間")
          end_date = django_filters.rest_framework.DateTimeFilter(field_name='create_time', lookup_expr='lte',
                                                                  label="結束時間")
          handler = django_filters.CharFilter(method='handler_filter', label="待處理人")
          is_flavor = django_filters.CharFilter(method='is_flavor_filter', label="收藏工單")
      
          @staticmethod
          def is_flavor_filter(queryset, name, value):
              return queryset.filter(flavors__operator=value)
      
          @staticmethod
          def handler_filter(queryset, name, value):
              return queryset.filter(Q(cur_nodes_o__operator__icontains=value) | (Q(creator=value, status="entering"))) \
                  .distinct()
      
          class Meta:
              model = models.Order
              fields = ('creator', 'tenant', 'cur_slot', 'status', 'recheck', 'mould', 'order_no')

      生效

      class xxxxx(ReadOnlyViewSet):
          queryset = xxxxx.objects.all()
          serializer_class = ......
          filter_class = xxxxxFilter
          search_fields = (....)
          filter_fields = (....)
          ordering_fields = (....)
          ordering = (....)

      視圖類

      from django_filters.rest_framework import DjangoFilterBackend
      from rest_framework.authentication import SessionAuthentication, BasicAuthentication
      from rest_framework.filters import OrderingFilter
      from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination
      from rest_framework.permissions import IsAuthenticated
      from rest_framework.throttling import UserRateThrottle
      from rest_framework.views import exception_handler
      
      from rest_framework.views import APIView
      from rest_framework.viewsets import ModelViewSet
      from rest_framework.response import Response
      from rest_framework.decorators import action
      
      from .models import Book, Author, Publish
      
      from .serializers import BookSerializer, AuthorSerializer, PublishSerializer
      
      
      # 序列化相關的注釋解析
      class BooksView(ModelViewSet):
          queryset = Book.objects.all()
          serializer_class = BookSerializer
      
          def list(self, request, *args, **kwargs):
              books = Book.objects.all()
              # 多個對象的時候 要 many=True
              bs = BookSerializer(instance=books, many=True)  # instance 要被序列化的對象
              return Response(bs.data)
      
          def create(self, request, *args, **kwargs):
              """序列化器對數據類型的校驗
              1. 字段類型 int/char/data/bool/mail/uuid....
              2. 字段屬性 max_length/required/read_only
              3. 單字段 (方法)
              4. 多字段 (方法)
              5. 自定義 (方法)
              """""
              print(request.data)
              """
              {
                  "csrfmiddlewaretoken": "o1XJ6weot4dx4fXwgIC2goYW3aeHUXer4IsIVoL7oyw31gfAi7TTUsTjnxBn9X0F",
                  "title": "海洋之歌",
                  "collect_num": "999"
              }
              """
              bs = BookSerializer(data=request.data)  # 把數據序列化 用 data 參數傳遞
              if bs.is_valid(raise_exception=True):  # True / False
                  # raise_exception 控制是否提示校驗不通過的信息報錯
                  """ 報錯回傳示例
                  HTTP 400 Bad Request
                  Allow: GET, POST, HEAD, OPTIONS
                  Content-Type: application/json
                  Vary: Accept
                  
                  {
                      "title": [
                          "該字段不能為空。"
                      ],
                      "collect_num": [
                          "請填寫合法的整數值。"
                      ]
                  }
                  """
                  bs.save()  # 調用序列化器里面執行 create 方法
                  return Response(bs.data)
      
          def update(self, request, *args, **kwargs):
              book = Book.objects.get(id=kwargs["pk"])
              # instance 要更新的對象, data 更新的數據
              bs = BookSerializer(instance=book, data=request.data)
              if bs.is_valid(raise_exception=True):  # 校驗
                  bs.save()  # 入庫
                  return Response(bs.data)
      
      # 視圖類的相關注解
      # 0.視圖類繼承關系
      """
      from rest_framework.viewsets import ModelViewSet
      ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet)
      
      from rest_framework.viewsets import ReadOnlyModelViewSet
      ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                           mixins.ListModelMixin,
                           GenericViewSet)             
      
      from rest_framework.generics import CreateAPIView.....
      CreateAPIView(mixins.CreateModelMixin, GenericAPIView)
      ListAPIView(mixins.ListModelMixin, GenericAPIView)
      RetrieveAPIView(mixins.RetrieveModelMixin, GenericAPIView)
      .....
      
      
                        
          from rest_framework import mixins
          mixins
              CreateModelMixin - >    create()
              CreateModelMixin - >    list()
              RetrieveModelMixin - >    retrieve()
              UpdateModelMixin - >    update()
              DestroyModelMixin - >    destroy()
              
          from rest_framework.viewsets import GenericViewSet        
          GenericViewSet(ViewSetMixin, generics.GenericAPIView):                   
      
              ViewSetMixin.as_view()       
                          self.request = request
                          self.args = args
                          self.kwargs = kwargs
                          return self.dispatch(request, *args, **kwargs)
              
              GenericAPIView.(views.APIView)
                          get_queryset()
                          get_object()
                          get_serializer()
                          filter_queryset()
                          paginate_queryset()
                          
                  APIView(View):
                      as_view()   
                      check_permissions()
                      ...
                  
                  
      """
      # 1. request 的參數獲取
      """
      request.GET - > request.query_params
      request.POST / body - > request.data
      """
      # 2. 視圖返回封裝
      """
      HttpResponse/JsonResponse..... -> 
          Response(data=None, status=None, template_name=None, headers=None, exception=False, content_type=None)
      """
      # 3. 返回狀態碼封裝
      """
      from rest_framework import status
      status.HTTP_100_CONTINUE....
      """
      # 4. 方法封裝
      """
      get - > list / retrieve
      post - > create
      put - > update
      delete - > destroy
      """
      # 5. 常用屬性行為對象封裝
      """
      GenericAPIView: 
          queryset = None 
          serializer_class = None
          lookup_field = 'pk' # 默認查詢字段
          lookup_url_kwarg = None
          
          
          # 使用示例
          # queryset = Author.objects.all()
          # serializer_class = AuthorSerializer
          
          filter_backends = api_settings.DEFAULT_FILTER_BACKENDS # 過濾器
          pagination_class = api_settings.DEFAULT_PAGINATION_CLASS # 分頁器
          
          get_queryset()
          get_serializer()
          get_object() # 基于 lookup_field  / lookup_url_kwarg
      """
      # 6. CURD 封裝
      """
      ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet)
      """
      
      
      class AuthorsView(ModelViewSet):
          queryset = Author.objects.all()  # 可以被使用 self.get_queryset() 的地方調用到
          serializer_class = AuthorSerializer  # 可以被使用 self.get_serializer() 的地方調用到
          lookup_url_kwarg = "id"  # 優先級比 lookup_field 高, 源碼: lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
          # 默認就是 pk
          lookup_field = "pk"  # lookup_url_kwarg / lookup_field 設定的值必須是數據庫有的字段
      
          def list(self, request, *args, **kwargs):
              # 動態查詢
              """
              不要使用 
              authors = self.queryset 
              動態查詢是沒法自動拿到 .all() 的, 因此調用的時候還需要自己再加上 .all()
              要不這樣 
              authors = self.queryset.all()
              或者這樣
              authors = self.get_queryset()
              """""
              authors = self.get_queryset()  # self.queryset
              authors_serializer = self.get_serializer()  # self.serializer_class
      
          def retrieve(self, request, *args, **kwargs):
              # author = self.queryset.get(kwargs["id"])
              author = self.get_object()  # 等價上面
      
      
      # 自定義分頁器
      class MyPageNumberPagination(PageNumberPagination):
          page_size = 1000  # 復寫全局的頁面大小
          page_size_query_param = 'page_size'  # 前段指定每頁大小的定義字段
          max_page_size = 10000  # 每頁最大可以指定的數量, 為了防止前段穿過來 page_size=100000000000000這樣的情況
      
      
      # 自定義異常處理
      def my_exception_handler(exc, context):
          response = exception_handler(exc, context)
      
          if response is not None:
              # APIException 類的異常
              response.data['status_code'] = response.status_code
          # 其他異常類型自定義處理
          else:
              from django.db import DatabaseError
              if isinstance(exc, DatabaseError):
                  return Response("數據庫我特么裂開")
              else:
                  return Response("其他異常")
      
          return Response("假設這里是個很好看的 404頁面")
      
      
      # 自定義方法/權限/認證/頻率/分頁/過濾/排序/異常處理/文檔 相關注釋
      class PublishesView(ModelViewSet):
          """ # 文檔里面的注釋信息
          list:
              獲取所有出版社
          """
          queryset = Publish.objects.all()
          serializer_class = PublishSerializer
          """局部認證是完全替換全局, 而非取并集, 即兩種同時配置, 局部生效, 全局失效"""
          # 局部認證
          authentication_classes = [SessionAuthentication, BasicAuthentication]
          # 局部權限
          permission_classes = [IsAuthenticated]
          # 局部限流
          throttle_classes = [UserRateThrottle]
          # throttle_scope = "yangtuo"    # 限流器使用 ScopedRateThrottle 時的映射字段
          # 局部分頁器
          pagination_class = MyPageNumberPagination  # 可使用自定義分頁器, 復寫 PageNumberPagination 的屬性實現自定義字段生效
          # 過濾器 搜索 / 排序
          filter_backends = [DjangoFilterBackend,
                             OrderingFilter]  # 注意導入的時候  from rest_framework.filters import OrderingFilter
          filterset_fields = ['name', 'create_dt', 'id']
          ordering_fields = ['id', 'create_dt']  # ordering 前段參數 倒敘加個 -
      
          # 自定義接口方法, 以及生成路由
          @action(methods=['GET'], detail=False)  # detail 表示是否有參數
          def get_yangtuo_publish(self, request):
              publishes = Publish.objects.filter(name__contains="羊駝")
              publish_serializer = self.serializer_class(instance=publishes, many=True)
              return Response(publish_serializer.data)
      
          # 額外添加參數, 更新局部信息
          @action(methods=['PUT'], detail=True)
          def change_publish(self, request, pk):
              publish = self.get_object()
              data = request.data
              # partial 參數攜帶表示只對部分數據進行校驗保存
              publish_serializer = self.serializer_class(instance=publish, data=data, partial=True)
              if publish_serializer.is_valid(raise_exception=True):
                  publish_serializer.save()
                  return Response(publish_serializer.data)

       

      posted @ 2021-06-14 17:07  羊駝之歌  閱讀(398)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品一区二区免费不卡| 国产精品大全中文字幕| 精品中文人妻在线不卡| 亚洲少妇人妻无码视频| 亚洲男人成人性天堂网站| 国产色无码精品视频免费| 久久精品蜜芽亚洲国产AV| 国产美女MM131爽爽爽| 府谷县| 国产欧美在线手机视频| 亚洲成a人v欧美综合天堂下载 | 精品无码中文视频在线观看| 四虎国产精品久久免费地址| 武鸣县| 免费人成在线观看网站 | 午夜一区二区三区视频| 夜夜爽77777妓女免费看| 日韩加勒比一本无码精品| 蜜桃av色偷偷av老熟女| 精品无码国产污污污免费| 日本一区二区三区内射| 亚洲精品自拍在线视频| 九九热视频精选在线播放| 日韩有码中文字幕国产| 国产蜜臀av在线一区二区| 在线播放深夜精品三级| 躁躁躁日日躁| 久久精品一本到东京热| 欧美成本人视频免费播放| 少妇做爰免费视看片| 99网友自拍视频在线| 99精品热在线在线观看视| 中文字幕亚洲制服在线看| AV无码免费不卡在线观看| 夜鲁鲁鲁夜夜综合视频| 亚洲人成网线在线播放VA| 午夜毛片精彩毛片| 国产超碰人人爽人人做| 国产永久免费高清在线观看| 人人玩人人添人人澡超碰| 无码里番纯肉h在线网站|