角色的权限控制

一、项目需求

'''
    1、自定义User表,新增mobile唯一约束字段,新增icon图片字段
    2、在自定义user表基础上,用GenericViewSet + CreateModelMixin + serializer 完成User表新增接口(就是注册接口),需要重写create,不然密码是明文
    3、在自定义user表基础上,用GenericViewSet + RetrieveModelMixin + serializer 完成User表单查(就是用户中心)
    4、在自定义user表基础上,用GenericViewSet + UpdateModelMixin + serializer 完成头像修改
'''

1、models.py

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


class User(AbstractUser):
    phone = models.CharField(max_length=11, unique=True)  # 唯一
    icon = models.ImageField(upload_to='icon', default='icon/default.png')  # 需要配置media文件夹,上传的文件回到media里

2、serializer.py

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


class UserModelSerializer(serializers.ModelSerializer):
    re_password = serializers.CharField(max_length=32, required=True, write_only=True)  # 因为表里没有,需要定义一个字段

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

    # 局部钩子
    def validate_phone(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('两次密码不一致')
        # 需要去除re_password,因为表里没有re_password字段
        attrs.pop('re_password')
        return attrs

    # 重写create方法
    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)  # 掉了会密码加密
        return user

3、路由分发urls.py

# 项目
from django.contrib import admin
from django.urls import path, include,re_path
from django.views.static import serve  # django内置的视图函数
from django.conf import settings

urlpatterns = [
    path('admin/', admin.site.urls),
    # 路由分发
    path('api/', include('api.urls')),
    # 开放media文件夹
    re_path('media/(?P<path>.*)', serve,{'document_root':settings.MEDIA_ROOT}),

]

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

router = SimpleRouter()
router.register('register', views.RegisterView, 'register')
print(router.urls)
urlpatterns = [
    # path('register/', views.RegisterView.as_view({'post':'create'})),
]

urlpatterns += router.urls

4、views.py

from django.shortcuts import render

# Create your views here.

from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import CreateModelMixin
from api.serializer import UserModelSerializer
from api.models import User

# 注册接口
class RegisterView(GenericViewSet, CreateModelMixin):
    queryset = User.objects.all()
    serializer_class = UserModelSerializer

5、settion.py

# 注册
INSTALLED_APPS = [
    'rest_framework'
]

# 扩展user表
AUTH_USER_MODEL = 'api.user'

# 配置头像相关
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

6、切换实例化类

'''
假设get请求和post请求,用的序列化类不一样,如果处理?
重写get_serializer_class,返回什么,用的就是那个序列化类
注册用的序列化类是UserModelSerializer,查询用的序列化类是RetrieveModelMixin
'''

# views.py
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin, UpdateModelMixin

from api.serializer import UserModelSerializer, UserReadOnlyModelSerializer
from api.models import User


class RegisterView(GenericViewSet, CreateModelMixin, RetrieveModelMixin):
    queryset = User.objects.all()
    serializer_class = UserModelSerializer

    def get_serializer_class(self):   # 重写这个方法
        print(self.action)  # create,retrieve
        if self.action == 'create':   # 利用action属性实现切换类
            return UserModelSerializer
        elif self.action == 'retrieve':
            return UserReadOnlyModelSerializer
        
# serializer.py
class UserModelSerializer(serializers.ModelSerializer):  # 跟上面的一样
    class Meta:
        model = User
        
class UserReadOnlyModelSerializer(serializers.ModelSerializer):  # 新写的类
    class Meta:
        model = User
        fields = ['username', 'icon']

7、切换头像

# views.py
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import CreateModelMixin, RetrieveModelMixin, UpdateModelMixin
from api.serializer import UserModelSerializer, UserReadOnlyModelSerializer, UserImageModelSerializer
from api.models import User

# 使用什么功能,继承什么类
class RegisterView(GenericViewSet, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin):
    queryset = User.objects.all()
    serializer_class = UserModelSerializer

    def get_serializer_class(self):
        print(self.action)  # create,retrieve
        if self.action == 'create':
            return UserModelSerializer
        elif self.action == 'retrieve':
            return UserReadOnlyModelSerializer
        elif self.action == 'update':   # 判断是否是update,返回该序列化类
            return UserImageModelSerializer
        
# serializer.py
class UserImageModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['icon']

角色的权限控制

上一篇:Android自定义动态布局 — 多图片上传,腾讯T3团队整理


下一篇:内存数据库(sqlite)和 map数据结构 做缓存对比