1. 程式人生 > 其它 >DAY 143 DRF-Django rest framework

DAY 143 DRF-Django rest framework

DRF-Django rest framework

1. 修改刪除介面

views.py

serializer.py

2. 高階用法之source

3. 模型類序列化器

4. 高階用法之SerializerMethodField

# 方式一 BookSerializer + SerializerMethodField
class BookSerializer(serializers.Serializer):
  id = serializers.IntegerField(required=False)
  name = serializers.CharField(max_length=32,min_length=2,source='title')
  price = serializers.DecimalField(max_digits=5, decimal_places=2)
  publish = serializers.SerializerMethodField()
  def get_publish(self,obj):
    dic={'name':obj.publish.name,'addr':obj.publish.addr}
    return dic

# 方式二 BookModelSerializer + SerializerMethodField
class BookModelSerializer(serializers.ModelSerializer):
  class Meta:
    model = models.Book
    fields = '__all__'
  publish = serializers.SerializerMethodField()
  def get_publish(self,obj):
    dic={'name':obj.publish.name,'addr':obj.publish.addr}
    return dic

# 方式三 使用序列化類的巢狀
class PublishSerializer(serializers.ModelSerializer):
  class Meta:
    model = models.Publish
    # fields = '__all__'
    fields = ['name','addr']

class BookModelSerializer(serializers.ModelSerializer):
  publish = PublishSerializer()
  class Meta:
    model = models.Book
    fields = '__all__'

5. drf的請求與相應

# Request
-data :前端以post請求提交的資料都在它中
-FILES :前端提交的檔案
-query_params:就是原來的request.GET
-重寫了 __getattr__
-使用新的request.method其實取得就是原生request.method(通過反射實現)

# Response
-from rest_framework.response import Response
-data:響應的字典
-status:http響應的狀態碼
-drf提供給你了所有的狀態碼,以及它的意思
from rest_framework.status import HTTP_201_CREATED
-template_name:模板名字(一般不動),瞭解
-headers:響應頭,字典
-content_type:響應的編碼方式,瞭解

# 自己封裝一個Response物件
class CommonResponse:
  def __init__(self):
    self.code=100
    self.msg=''
  @property
  def get_dic(self):
    return self.__dict__

# 通過配置,選擇預設模板的顯示形式(瀏覽器方式,json方式)
-配置檔案方式(全域性)
-如果沒有配置,預設有瀏覽器和json
-drf有預設配置檔案
from rest_framework.settings import DEFAULTS
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ( # 預設響應渲染類
'rest_framework.renderers.JSONRenderer', # json渲染器
'rest_framework.renderers.BrowsableAPIRenderer', # 瀏覽API渲染器
)}
-在檢視類中配置(區域性)
-粒度更小
-class BookDetail(APIView):
renderer_classes=[JSONRenderer,]

6. many=True

7. 區域性全域性鉤子原始碼解析

# 區域性全域性鉤子原始碼解析
入口是is_valid()
=> BaseSerializer => is_valid
=> self._validated_data
=> self.run_validation(self.initial_data)
=> Serializer這個類的:self.run_validation

# 重寫父類Field的run_validation方法
class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
  ......

  def run_validation(self, data=empty):
  """
  We override the default `run_validation`, because the validation
  performed by validators and the `.validate()` method should
  be coerced into an error dictionary with a 'non_fields_error' key.
  """
  # 驗證空值
  (is_empty_value, data) = self.validate_empty_values(data)
  # 是空值返回data
  if is_empty_value:
    return data
  # 區域性欄位的校驗和區域性鉤子校驗 返回OrderedDict()例項化物件
  value = self.to_internal_value(data)
  try:
    # 執行驗證器
    self.run_validators(value)
    # 全域性鉤子的校驗
    value = self.validate(value)
    """
    這裡的全域性鉤子如果我們需要使用的時候,需要重寫,重寫的時候一定要返回被拿出來驗證的屬性
    def validate(self, attrs):
      return attrs
    """
  except (ValidationError, DjangoValidationError) as exc:
    raise ValidationError(detail=as_serializer_error(exc))
  return value