DRF中通過請求方式不同使用不同的序列化器
阿新 • • 發佈:2022-05-23
models.py 模型類
from django.db import models from django.contrib.auth.models import AbstractUser class User(AbstractUser): phone = models.CharField(max_length=32,unique=True) # 唯一 icon = models.ImageField(upload_to='icon',default='icon/default.png') # 需要配置media資料夾 上傳檔案會預設放到media/icon資料夾下
gerneral_ser.py 序列化器
from api import models from rest_framework import serializers from rest_framework.validators import ValidationError # 當註冊時用UserModelSerializer序列化器 class UserModelSerializer(serializers.ModelSerializer): # re_password這個欄位必須設定write_only 因為模型類中沒有該欄位 re_password = serializers.CharField(max_length=16,required=True,write_only=True)class Meta: model = models.User fields = ['username','password','re_password','phone','icon'] extra_kwargs = { 'password':{'write_only':True}, } # 區域性鉤子 校驗手機號是否合法 def validate_phone(self,data): if len(data) == 11: return dataelse: raise ValidationError('手機號必須是11位') # 區域性鉤子 校驗使用者名稱是否存在 def validated_username(self,data): user_obj = models.User.objects.filter(username=data) if user_obj: raise ValidationError('使用者名稱已經存在') else: return data # 全域性鉤子 校驗兩次密碼是否相同 def validate(self, attrs): if attrs.get('password') == attrs.get('re_password'): # 直接在這裡將確認密碼刪除 後續可以直接將資料存入資料庫 attrs.pop('re_password') return attrs else: raise ValidationError('兩次密碼不一致') def create(self, validated_data): # models.User.objects.create(**validated_data) # 儲存的密碼是明文的 不行 # 如果上面的全域性鉤子沒有刪除確認密碼 在這裡刪除也可以 # validated_data.pop('re_password') user_obj = models.User.objects.create_user(**validated_data) return user_obj # 當查詢單個時用UserReadOnlySerializer序列化器 class UserReadOnlySerializer(serializers.ModelSerializer): class Meta: model = models.User fields = ['username','icon']
views.py檢視
from api import models,ser from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import CreateModelMixin,RetrieveModelMixin class RegisterView(GenericViewSet,CreateModelMixin,RetrieveModelMixin): queryset = models.User.objects.all() # serializer_class = ser.UserModelSerializer # 通過請求方式不同使用不同的序列化器 # 重寫get_get_serializer_class(self)方法 def get_serializer_class(self): if self.action == 'create': print('我是註冊') return ser.UserModelSerializer elif self.action == 'retrieve': print('我是查詢') return ser.UserReadOnlySerializer
urls.py 路由
from django.urls import path,re_path from api import views from rest_framework import routers router = routers.SimpleRouter() router.register('register',views.RegisterView) urlpatterns = [] urlpatterns += router.urls
總結:
我們可以通過重寫get_serializer_class(self)方法,來控制不同的請求方式使用不同的序列化器
這裡我們繼承的是Viewset檢視集,可以通過action引數來判斷
如果我們繼承的是APIView或者GenericAPIView,可以通過request.method來判斷