DRF中通过请求方式不同使用不同的序列化器
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 data else: 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'] # 当修改时用UserUpdateSerializer序列化器 class UserUpdateSerializer(serializers.ModelSerializer): class Meta: model = models.User fields = ['icon']
views.py视图
from api import models,ser from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import CreateModelMixin,RetrieveModelMixin,UpdateModelMixin class RegisterView(GenericViewSet,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin): queryset = models.User.objects.all() # serializer_class = ser.UserModelSerializer # 通过请求方式不同使用不同的序列化器 # 重写get_serializer_class(self)方法 # 通过action参数来判断用哪个序列化器 def get_serializer_class(self): if self.action == 'create': print('我是注册') return ser.UserModelSerializer elif self.action == 'retrieve': print('我是查询') return ser.UserReadOnlySerializer elif self.action == 'update': print('我是修改') return ser.UserUpdateSerializer
修改时通过postman对http://127.0.0.1:8000/api/register/2/发起put请求
通过选择form-data格式,key传入icon,选择files,value选择图片,即可修改头像
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来判断