Django之drf 之二 数据的修改与删除,字段的高级用法sourse,模型类序列化器,高级用法之SerializerMethodField drf的请求与响应 many=True源码分析,及局部全局钩子源码解析
數據的修改與刪除,字段的高級用法sourse,模型類序列化器,高級用法之SerializerMethodField drf的請求與響應 many=True源碼分析,及局部全局鉤子源碼解析
一、 修改,刪除接口
views.py
def put(self, request, id):
# 通過id取到對象
res = {'code': 100, 'msg': ''}
try:
book = models.Book.objects.get(id=id)
ser = BookSerializer(instance=book, data=request.data)
ser.is_valid(raise_exception=True)
ser.save()
res['msg'] = '修改成功'
res['result'] = ser.data
except Exception as e:
res['code'] = 101
res['msg'] = str(e)
return Response(res)
def delete(self,request,id):
response = {'code': 100, 'msg': '刪除成功'}
models.Book.objects.filter(id=id).delete()
return Response(response)
serializer.py
class BookSerializer(serializers.Serializer):
id = serializers.IntegerField(required=False)
title = serializers.CharField(max_length=32,min_length=2)
price = serializers.DecimalField(max_digits=5, decimal_places=2)
publish = serializers.CharField(max_length=32)
def create(self, validated_data):
res=models.Book.objects.create(**validated_data)
print(res)
return res
def update(self, book, validated_data):
book.title=validated_data.get('title')
book.price=validated_data.get('price')
book.publish=validated_data.get('publish')
book.save()
return book
二、高級用法之source修改返回到前端的字段名
1.#source = title 字段名就不能叫title
#source = '字段名' 該字段名必須是表中擁有的,然后賦值給name(自己想要在前端看到的字段名)
name = serializers.CharField(max_length=32,min_length=2,source='title')
2 如果表模型中有方法
#執行表模型中的方法,并且把返回值賦值給xxx,且xxx這個變量名的命名不能與test相同
xxx = serializers.CharField(source='test')
3 source支持跨表操作
addr = serializers.CharField(source='publish.addr')
有時間去看源碼
3模型類序列化器
1 原來用的Serilizer跟表模型沒有直接聯系,模型類序列化ModelSerilizer,跟表模型有對應關系
2 使用
class BookModelSerializer(serializers.ModelSerializer):
model=models.Book (表模型) #跟那個表模型建立關系
fields=[字段,字段] #序列化的字段,反序列化的字段
fields='__all__' #所有字段都序列化反序列化
exclude=[字段,字段] #排除那些字段(不能跟fields同時使用)
read_only_fields=['price','publish'] #序列化顯示的字段
weite_only_fields=['title'] #反序列化需要傳入的字段
extra_kwargs = {'title':{'max_length':32,'write_only':True}}
depth = 1 #了解,跨表1查詢,最多建議寫3
#重寫某些字段
publish = serializers.CharField(max_length=32,source='publish.name')
#局部鉤子,全局鉤子,跟原來完全一樣
3 新增,修改
-統統不用重寫create和update方法了,在ModelSerializer中重寫了create和update
四高級用法之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() #必須與get_字段名一起使用
def get_publish(self,obj): (需要2個參數,第二個參數obj是當前表的對象)
dic={'name':obj.publish.name,'addr':obj.publish.addr}
return dic
class BookModelSerializer(serializers.ModelSerializer): #用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__'
五、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__
# 自己封裝一個response,繼承drf的Response
# 通過配置,選擇默認模板的顯示形式(瀏覽器方式,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,]
六、 many=True源碼分析,局部全局鉤子
1 many=True
-__init__----->一路找到了BaseSerializer---》__new__決定了生成的對象是誰
# __new__如果有many會生成一個類似于列表的對象,列表內放置了多個serializer,沒有會生成單個的serializer對象
2 入口是is_valid()---》BaseSerializer--》is_valid---》self._validated_data = self.run_validation(self.initial_data)
-Serializer這個類的:self.run_validation
"""
is_valid可以在BaseSerializer類中找到 在is_valid中有 self._validated_data = self.run_validation(self.initial_data)(可以在Serializer類中找到)
value = self.to_internal_value(data)(data指的是字段的值)在該方法中,通過循環判斷是否有局部鉤子,如果有進行局部校驗,有報錯,通過Except接收返回,沒有直接返回該字段值。
"""
def run_validation(self, data=empty): value = self.to_internal_value(data) # 局部字段自己的校驗和局部鉤子校驗 try: self.run_validators(value) value = self.validate(value) # 全局鉤子的校驗 except (ValidationError, DjangoValidationError) as exc: raise ValidationError(detail=as_serializer_error(exc)) return value
總結
以上是生活随笔為你收集整理的Django之drf 之二 数据的修改与删除,字段的高级用法sourse,模型类序列化器,高级用法之SerializerMethodField drf的请求与响应 many=True源码分析,及局部全局钩子源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里花名推荐
- 下一篇: 要怎么设置路由器如何管理路由器的设置