drf—— 登录接口,实现头像修改

要求

1 自定义User表扩展auth的User,新增mobile唯一约束字段;新增icon图片字段
2 在自定义User表基础上,用 GenericViewSet + CreateModelMixin + serializer 完成User表新增接口(就是注册接口)
(重要提示:序列化类要重写create方法,不然密码就是明文了)
3 在自定义User表基础上,用 GenericViewSet + RetrieveModelMixin + serializer 完成User表单查(就是用户中心) 4 在自定义User表基础上,用 GenericViewSet + UpdateModelMixin + serializer 完成用户头像的修改

代码

models.py --->数据迁移

from django.db import models
from django.contrib.auth.models import AbstractUser


class UserInfo(AbstractUser):
    mobile = models.CharField(max_length=32, unique=True)
    icon = models.ImageField(upload_to='head', default='head/default.png')

settings.py

INSTALLED_APPS = [
    ...
    'rest_framework'
]

#打开media路径
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
#扩写auth_user表
AUTH_USER_MODEL = 'app01.UserInfo'

views.py

from django.shortcuts import render

from app01.models import UserInfo
from app01.serializer import UserModelSerializer, UserReadOnlyModelSerializer, UserIconModelSerializer
from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin, UpdateModelMixin
from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import GenericViewSet, ViewSetMixin


# ViewSetMixin:路由写法变了,自动生成路由
# GenericAPIView:必须指定queryset和serializer
class UserView(GenericViewSet, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin):
    # class UserView(ViewSetMixin,GenericAPIView,CreateModelMixin):
    queryset = UserInfo.objects.all()
    serializer_class = UserModelSerializer

    # 重写get_serializer_class方法,实现不同的请求,返回的序列化类不一样
    def get_serializer_class(self):
        # 可以根据请求方式
        if self.action == 'create':
            return UserModelSerializer
        elif self.action == 'retrieve':
            return UserReadOnlyModelSerializer
    #更改头像
elif self.action == 'update': return UserIconModelSerializer

serializer.py

from rest_framework import serializers
from app01.models import UserInfo
from rest_framework.exceptions import ValidationError

class UserModelSerializer(serializers.ModelSerializer): # 注册功能,需要的字段 # username,password,re_password,mobile # 这个字段在表中没有,写成write_only=True re_password = serializers.CharField(max_length=18, min_length=3, required=True, write_only=True) class Meta: model = UserInfo fields = ['username', 'password', 'mobile', 're_password', 'icon'] extra_kwargs = { 'username': {'max_length': 12, 'min_length': 3}, 'password': {'write_only': True}, 'icon': {'read_only': True} } # 写mobile的局部钩子 def validate_mobile(self, data): if len(data) == 11: return data else: raise ValidationError('手机号不合法') # 全局钩子校验两次密码是否一致 def validate(self, attrs): password = attrs.get('password') re_password = attrs.get('re_password') if password == re_password: # re_password不存数据库,剔除 attrs.pop('re_password') return attrs else: raise ValidationError('两次密码不一致') ## 重写create方法,实现密码的加密 #序列化类要重写create方法,不然密码就是明文了 def create(self, validated_data): # re_password也可也在这里移除 # UserInfo.objects.create(**validated_data) # 密码是明文 user = UserInfo.objects.create_user(**validated_data) return user # 注意不要忘了这句话 # 序列化的时候后 # 一个模型类,不一定对着一个序列化类 # 只做序列化用 class UserReadOnlyModelSerializer(serializers.ModelSerializer): class Meta: model = UserInfo fields = ['username', 'mobile', 'icon', 'email', 'date_joined'] # 这个序列化类,只做修改头像用 class UserIconModelSerializer(serializers.ModelSerializer): class Meta: model = UserInfo fields = ['icon', ]

路由分发app01/urls.py

from app01 import views


# 自动生成路由
from rest_framework.routers import SimpleRouter

router = SimpleRouter()
router.register('user', views.UserView)
# router.register('userinfo', views.UserReadOnlyView)

urlpatterns = [
...
]

urlpatterns += router.urls

总路由urls.py

from django.contrib import admin
from django.urls import path,include,re_path
from django.views.static import serve
from django.conf import settings

urlpatterns
= [ path('admin/', admin.site.urls), path('homework/', include('app01.urls')), re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}), ]
原文地址:https://www.cnblogs.com/guojieying/p/13966253.html