APIView+Serializers的使用

滿心歡喜...發表於2020-09-28

1.APIview使用

https://www.cnblogs.com/xiaonq/p/10124104.html

  • ModelVIewSet是對APIView封裝
  • ModelSerializer是對Serializers

1.1在user/urls.py

urlpatterns = [
path(‘apiview/’,views.UserInfroViewSet.as_view()),
]

1.2建立User/serializers.py

  • serializers.ModelSerializer和serializers.Serializer field引數說明
    ‘’’ field引數 ‘’’
    1.read_only
    read_only = True 表示不允許使用者自己上傳,只能用於api的輸出,序列化的時候也不用對這個資料進行驗證,序列化返回是有改欄位
    2.write——only
    write_only=True 表示在更新或建立例項時可以使用該欄位,但在序列化返回時不包括該欄位。
    3.required=True :該欄位是必須的,不能為空
    required=True 反序列化(前端返回資料必須包含此欄位)的時候必須提供這個欄位 設定False可以不提供
    4.allow_null/allow_blank:該欄位允許為null/空 allow_null=True 可以為null 設定False則不能為null
    5.label:標籤,用於對欄位顯示設定
    6.help_text:對欄位進行解釋的一段文字,用於提示
    7.style:說明欄位的型別
    8.error_messages:欄位出錯時,資訊提示
  • 建立user/serializers.py寫序列化器
#class User(AbstractUser):
#	phone = models.CharField('手機號',max_length=20)
#	img = models.ImageField(upload_to='user',null=True) 
#	nick_name = models.CharField('暱稱',max_length=20)
#	address = models.CharField('地址',max_length=255)

class UserInfoSerializer(serializers.Serializer):
	id = serializers.CharField(read_only=True) # 普通欄位,設定id為只讀欄位,不能修改 
	username = serializers.CharField(min_length=3,max_length=20,error_messages= {'required': '該欄位必填'}) # 顯示普通欄位 
	img = serializers.ImageField(required=False) 
	nick_name = serializers.CharField(max_length=20) 					   			
	address = serializers.CharField(max_length=255) 
	xxx = serializers.SerializerMethodField(read_only=True) 自定義顯示(顯示多對 多) 

	class Meta: 
		model = User 	
	# 自定義顯示 多對多 欄位
	def get_xxx(self,row): 
	'''row: 傳過來的正是 User表的物件''' 
	users = row.username # 獲取使用者名稱 
	return users
	# 定義建立語法:ser.save()執行,就會立刻呼叫create方法用來建立資料 
	def create(self, validated_data):
		 '''validated_data: 表單或者vue請求攜帶的json: {"username":"zhangsan","password":"123456"}''' 
	 # https://www.cnblogs.com/xiaonq/p/7978409.html 
	 	return User.objects.create(**validated_data) 
	 	# 定義更新方法 
	 def update(self, instance, validated_data): 
	 ''' instance : 查詢的物件 validated_data : postman提交的json資料 {"username":"zhangsan","password":"123456"} ''' 				
	 	if validated_data.get('username'): 
	 		instance.username = validated_data['username'] 	
	 	instance.save() 
	 	return instance 
	 # 定義單一欄位驗證的方法 
	 def validate_name(self, value): 
	 	if value == 'root': 
	 		raise serializers.ValidationError('不能建立root管理員賬號') 
	 	return value 
	 	# 定義多欄位驗證方法 
	 	def validate(self, attrs): 
	 		print(attrs) 
	 		if attrs.get("username") == 'admin': 
	 			raise serializers.ValidationError('不能建立admin使用者') 
	 		return attrs

1.3在user/views.py中新增檢視函式

from user.serializers import UserInfoSerializer 
class UserInfoViewSet(APIView): 
	# 查詢使用者資訊 
	def get(self, request, *args, **kwargs): 
		# 一對多、多對多查詢都是一樣的語法 
		obj = User.objects.all() 
		ser = UserInfoSerializer(instance=obj,many=True) # 關聯資料多個 
		# ser = UserInfoSerializer(instance=obj[0]) # 關聯資料一個 
		return Response(ser.data, status=200) 
	# 建立使用者 
	'''建立使用者''' 
	def post(self,request): 
		ser = UserInfoSerializer(data=request.data) # 判斷提交資料是否合法 
		if ser.is_valid(): 
			ser.save()
			return Response(data=ser.data, status=201) 		
		return Response(data=ser.errors,status=400) 
	# 更新使用者資訊 
	def put(self, request): 
		pk = request.query_params.get('pk') 
		try:
			userinfo = User.objects.get(id = pk) 
		except Exception as e: 
			return Response(data='使用者不存在', status=201)
		# 建立序列化物件,並將要反序列化的資料傳遞給data構造引數,進而進行驗證 
		ser = UserInfoSerializer(userinfo,data=request.data) 	
		if ser.is_valid(): 
			ser.save() 
			return Response(data=ser.data, status=201) 	
		return Response(data=ser.errors,status=400)

2.測試介面

2.1查詢所有使用者

http://192.168.56.100:8888/user/apiview/
在這裡插入圖片描述

2.2建立使用者

http://192.168.56.100:8888/user/apiview/在這裡插入圖片描述

2.3更新使用者資訊

http://192.168.56.100:8888/user/apiview/?pk=7
在這裡插入圖片描述

2.4限流功能測試

http://192.168.56.100:8888/user/apiview/ 
'''修改syl/settings.py配置限速設定''' 
REST_FRAMEWORK = { 
	#3.1 限流策略 
	'DEFAULT_THROTTLE_RATES': { 
		'user': '3/hour', # 認證使用者每小時10次
		'anon': '3/day',
	 },
 }