drf作业

作业:
1 自定义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

# Create your models here.
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    mobile=models.CharField(max_length=32,unique=True)  #唯一
    icon=models.ImageField(upload_to='icon',default='icon/default.png')  #需要配media文件夹,上传的文件就会放到media文件夹下的icon


class Book(models.Model):
    name = models.CharField(max_length=64)

    def __str__(self):
        return self.name


class Car(models.Model):
    name = models.CharField(max_length=64)

    def __str__(self):
        return self.name

settings.py

MEDIA_URL='/media/'
MEDIA_ROOT=os.path.join(BASE_DIR,'media')   #真正的文件夹路径

#指定使用的auth表是自己定义的
AUTH_USER_MODEL='api.User'   #app名.表名

总路由

from django.contrib import admin
from django.urls import path,re_path,include
from django.views.static import serve    # 暴露接口使用
from django.conf import settings  # 以后都用这个导配置文件,暴露接口

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('api.urls')),
    re_path(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})

]

api/urls.py

from django.urls import path,re_path,include
from api import views
from rest_framework.routers import SimpleRouter


router = SimpleRouter()
router.register('users', views.UserView,'users')
# 可以注册很多

urlpatterns = [
    # path('users/', views.UserView.as_view(action={'post':'create'})),  # 有问题
    path('', include(router.urls)),  # 第二种方式
    # 暴露后端指定文件夹资源,这样就会把files暴露给外界
]

# urlpatterns+=router.urls  # 一种方式

views.py

from django.shortcuts import render
from rest_framework.viewsets import GenericViewSet
# ViewSetMixin:重写了as_view,路由配置变样了, generics.GenericAPIView:只需要配俩东西
from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin
from api import models
from api import ser


# Create your views here.
class UserView(GenericViewSet, CreateModelMixin, RetrieveModelMixin):
    queryset = models.User.objects.all()
    serializer_class = ser.UserModelSerializer

    # 假设get请求和post请求,用的序列化类不一样,如何处理?
    # 重写getget_serializer_class,返回啥,用的序列号类就是啥
    # 注册,用的序列化类是UserModelSerializer,查询一个用的序列化类是UserReadOnlyModelSerializer
    def get_serializer_class(self):
        print(self.action)  # create,retrieve
        if self.action == 'create':
            return ser.UserModelSerializer
        elif self.action == 'retrieve':
            return ser.UserReadOnlyModelSerializer
        elif self.action == 'update':
            return ser.UserImageModelSerializer

ser.py

from rest_framework import serializers
from api import models
from rest_framework.exceptions import ValidationError


class UserModelSerializer(serializers.ModelSerializer):
    re_password = serializers.CharField(max_length=16, min_length=4, required=True,
                                        write_only=True)  # 因为re_password在表中没有,需要在这定义

    class Meta:
        model = models.User
        fields = ['username', 'password', 'mobile', 're_password', 'icon']
        extra_kwargs = {
            'username': {'max_length': 16},
            'password': {'write_only': True}
        }

    # 局部钩子
    def validate_mobile(self, data):
        if not len(data) == 11:
            raise ValidationError('手机号不合法')
        return data

    # 全局钩子
    def validate(self, attrs):
        if not attrs.get('password') == attrs.get('re_password'):
            raise ValidationError('两次密码不一致')
        attrs.pop('re_password')  # 剔除该字段,因为数据库没有这个字段
        return attrs

    def create(self, validated_data):
        # attrs.pop('re_password') 如果上面没有剔除,在这也可以
        # models.User.objects.create(**validated_data) 这个密码不会加密
        user = models.User.objects.create_user(**validated_data)
        return user


class UserReadOnlyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.User
        fields = ['username', 'icon']


class UserImageModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.User
        fields = ['icon']
原文地址:https://www.cnblogs.com/baicai37/p/13307783.html