个人博客系列-后端项目-系统角色配置(8)

系统角色配置需要设置的接口

用户可以绑定多个角色,角色对应有多个路由权限。用户绑定角色后,可以访问当前角色下的各个api路由和菜单路由。

  1. 用户注册时设置用户角色
  2. 修改用户角色(同时对应用户可以访问的路由将会同步变更)
  3. 添加修改用户角色
  4. 添加url路由和菜单路由
  5. 给角色添加或修改路由

1. 用户注册

class User(AbstractBaseUser):
    username = models.CharField(max_length=255, unique=True, verbose_name="手机号")
    password = models.CharField(max_length=255, unique=False, verbose_name="密码")
    is_vip = models.BooleanField(default=False,verbose_name="是否为vip")
    vip_expires_at = models.DateTimeField(auto_now_add=True,verbose_name="vip过期时间")
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(auto_now=True,verbose_name="最后登录时间")
    USERNAME_FIELD = 'username'

    def set_password(self, raw_password):
        self.password = make_password(raw_password)

    def check_password(self, raw_password):
        return check_password(raw_password, self.password)

    class Meta:
        db_table = "blog_user"
        verbose_name = "用户表"
        verbose_name_plural = verbose_name
    ## urls.py
    path("userregistry/", UserRegisterView.as_view(), name="userregistry")
## views.py
class UserRegisterView(GenericAPIView):
    # 注册接口,局部禁用用户验证和权限
    authentication_classes = ()
    permission_classes = ()
    serializer_class = RegisterSerializer
    def post(self, request, *args, **kwargs):
        res = self.get_serializer(data=request.data)
        res.is_valid(raise_exception=True)
        data = res.validated_data
        return Response({'msg': data})
    def delete(self, request, *args, **kwargs):
        self.delete(self, request, *args, **kwargs)
        return Response()
## serializer.py
from rest_framework import serializers
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from userauth.models import User
from systemauth.models import UserRole
class RegisterSerializer(serializers.Serializer):
    """
    注册用户信息序列化校验
    """
    username = serializers.CharField()
    password = serializers.CharField()
    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        if User.objects.filter(username=username).exists():
            raise serializers.ValidationError('用户名已被占用')
        print(password)
        if not password or len(password) < 6:
            raise serializers.ValidationError("密码不符合要求,请使用6位以上密码")
        if attrs.get("is_vip"):
            attrs['is_vip'] = False
        attrs['is_active'] = True
        # 将用户信息保存到数据库中
        user = User.objects.create(**attrs)
        # 为其设置角色为普通用户,2 在表中设置的是普通用户
        UserRole.objects.create(**{'user_id': user.id, 'role_id': 2})
        if user:
            # 签发token
            refresh = TokenObtainPairSerializer.get_token(user)
            data = {
                'code': 100,
                'message': '登录成功',
                'username': user.username,
                'refresh': str(refresh),
                'access': str(refresh.access_token),
            }
            return data
        else:
            raise serializers.ValidationError('用户注册失败')

API测试
在这里插入图片描述

2. 添加或修改用户角色

## models.py
class UserRole(models.Model):

    user_id = models.IntegerField('用户ID', null=True, blank=True)
    role_id = models.IntegerField('角色ID', null=True, blank=True)

    class Meta:
        db_table = "blog_user_role"
        verbose_name = "用户角色表"
        verbose_name_plural = verbose_name
## serializers.py
class UserRoleSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    user_id = serializers.IntegerField()
    role_id = serializers.IntegerField()
    role_name = serializers.SerializerMethodField()
	
	    def create(self, validated_data):
        if not UserRole.objects.filter(user_id=validated_data['user_id'],role_id=validated_data['role_id']).exists():
            return UserRole.objects.create(**validated_data)	

    def get_role_name(self, obj):
        role_name = Role.objects.get(id=obj.role_id).role_name
        return role_name
        
    class Meta:
        model = UserRole
        fields = '__all__'

## urls.py
from rest_framework import routers
from systemauth import views as system_views

router = routers.DefaultRouter()
router.register(r'role', system_views.RoleView, basename='role')
router.register(r'userrole', system_views.UserRoleViewSet, basename='userrole')

urlpatterns = [

]
urlpatterns += router.urls
## views.py
class UserRoleViewSet(ModelViewSet):
    queryset = UserRole.objects.all()
    serializer_class = UserRoleSerializer

3. 添加修改用户角色

## models.py
class Role(models.Model):
    role_name = models.CharField('角色名字', max_length=16)

    class Meta:
        db_table = "blog_role"
        verbose_name = "角色表"
        verbose_name_plural = verbose_name

    def __int__(self):
        return self.role_name
## serializer.py
class RoleSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    role_name = serializers.CharField()
    class Meta:
        model = Role
        fields = '__all__'

## urls.py
router.register(r'role', system_views.RoleView, basename='role')
## views.py
class RoleView(ModelViewSet):
    serializer_class = RoleSerializer
    queryset = Role.objects.all()

4. 添加或修改api路由和菜单路由

## models.py
class Access(models.Model):
    name = models.CharField('用户权限名称', max_length=256)
    path = models.CharField('用户权限路由', max_length=256)
    method = models.CharField('用户权限请求方式', max_length=16)
    types = models.CharField('权限类型', blank=True, null=True, max_length=10)  # 菜单权限和api权限

    class Meta:
        db_table = "blog_access"
        verbose_name = "权限表"
        verbose_name_plural = verbose_name
## serializers.py
class AccessSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)

    class Meta:
        model = Access
        fields = '__all__'

## views.py
class AccessConfigView(ModelViewSet):
    serializer_class = AccessSerializer
    queryset = Access.objects.all()

## urls.py
router.register(r'accessconfig', system_views.AccessConfigView, basename='accessconfig')

api测试
在这里插入图片描述

4. 给角色添加或修改路由

## models.py
class UserRole(models.Model):
    user_id = models.IntegerField('用户ID', null=True, blank=True)
    role_id = models.IntegerField('角色ID', null=True, blank=True)

    class Meta:
        db_table = "blog_user_role"
        verbose_name = "用户角色表"
        verbose_name_plural = verbose_name
## serializer.py
class ReleAccessSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    access_name = serializers.SerializerMethodField()

    def validate(self, value):
        if "role_id" not in value or "acc_id" not in value:
            raise ValidationError({"error": "参数错误"})
        return value

    def create(self, validated_data):
        if not RoleAccess.objects.filter(role_id=validated_data['role_id'], acc_id=validated_data['acc_id']).exists():
            return RoleAccess.objects.create(**validated_data)

    def get_access_name(self, obj):
        return Access.objects.get(id=obj.acc_id).name
    class Meta:
        model = RoleAccess
        fields = '__all__'
## views.py
class RoleAccessViewSet(ModelViewSet):
    serializer_class = ReleAccessSerializer
    queryset = RoleAccess.objects.all()

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data.get("roleaccess", list()), many=True)
        if serializer.is_valid():
            serializer.save()
            return Response({"success": True}, status=status.HTTP_200_OK)
        else:
            return Response({"success": False, "message": ''.join([''.join(err.get("error", [])) for err in serializer.errors])}, status=status.HTTP_400_BAD_REQUEST)
## urls.py
router.register(r'roleaccess', system_views.RoleAccessViewSet, basename='roleaccess')

接口测试

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/485347.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

有关AI的随笔(1)

随笔&#xff1a; 今天是周天&#xff0c;是个好日子&#xff0c;结果老师布置的诗还没写&#xff0c;只好去借助AI&#xff0c;结果我发现了几个有趣的问题&#xff1a; 1. AI写的诗是如何来的&#xff1f;通过数据库&#xff1f; 2. 它真的明白是什么意思吗&#xff1f;&…

AutoDL算力云进行yolov5训练流程

目录 第一步 充值第二步 选择我们用到的显卡第三步 将我们的yolov5源代码导入服务器第四步 激活环境第五步 训练第六步 训练完成 提取 第一步 充值 打开我们的算力云官网 然后找到充值入口 最低充值50 第二步 选择我们用到的显卡 一般呢我都用便宜的2080ti 选择2080ti之后 基…

前端学习之用css和html做一个仿淘宝的导航栏

代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>仿淘宝界面案例</title><style>/* 最外层盒子 */.container{width: 270px;height: 385px;border: 1px solid rgb(255, 208, 0);bord…

【jvm】ParNew和ParallelOld为什么不能一起使用

java垃圾回收器ParNew和ParallelOld为什么不能一起使用 Java垃圾回收器中的ParNew和ParallelOld不能一起使用的原因在于它们的设计和目标不同&#xff0c;以及它们所属的垃圾回收器系列不同。 设计和目标差异&#xff1a; ParNew 收集器是 Serial 收集器的并行版本&#xff0c…

【计算机网络】物理层

文章目录 第二章 物理层一、 物理层的基本概念1. 物理层接口特性 二、数据通信基础1. 典型的数据通信模型2. 数据通信相关术语3. 设计数据通信系统要考虑的3个问题4. 三种通信方式5. 串行传输&并行传输6. 同步传输&异步传输7. 码元8. 数字通信系统数据传输速率的两种表…

Python入门(六)

参数传递 1.普通传参 通过判断对应位置来传递。 2.关键字传参 用关键字(Keyword&#xff09;的方式来传递参数。在定义函数时&#xff0c;我们给了形参一个符号标记&#xff0c;即参数名。关键字传递是根据参数名来让数据与符号对应上。因此&#xff0c;如果在调用时使用关键…

Vite+Vue3+TS+Vue-Router+Axios+Pinia开发模板

一、模板介绍 VUE3开发全家桶模板&#xff0c;安装了ts,router,axios,pinia并提供了简单示例并提供了它们的官网链接。 对axios进行了简单封装。 二、下载地址 https://github.com/yigedayouzi/ViteTemplateOne 三、快速开始 1、git clone gitgithub.com:yigedayouzi/Vite…

鸿蒙实战开发:【7日天气预报】

先来看一下效果 本项目界面搭建基于ArkUI中TS扩展的声明式开发范式&#xff0c; 数据接口是[和风&#xff08;天气预报&#xff09;]&#xff0c; 使用ArkUI自带的网络请求调用接口。 我想要实现的一个功能是&#xff0c;查询当前城市的实时天气&#xff0c; 目前已实现的功…

IDEA, Pycharm, Goland控制台乱码

IDEA, Pycharm, Goland控制台乱码 问题描述: 控制台出现&#xfffd;&#xfffd;&#xfffd;&#xfffd;等乱码 复现频率: 总是 解决方案: 以IDEA为例 添加 -Dfile.encodingUTF-8位置 idea64.exe.vmoptions 在安装idea的bin目录idea.vmoptions idea客户端 示意图

我的风采——android studio

目录 实现“我的风采”页面要求理论代码生成apk文件 实现“我的风采”页面 要求 要求利用’java框架的边框布局实现“找的风采 ”页而&#xff0c;其中中间为你的生活照&#xff0c;左右和下面为按钮&#xff0c;上面为标签 理论 Java GUI编程是Java程序设计的重要组成部分…

设计模式(十二):中介者模式(行为型模式)

Mediator&#xff0c;中介者模式&#xff1a;用一个中介对象封装一些列的对象交互。属于行为型模式 Facade&#xff0c;外观模式&#xff1a;为子系统中的一组接口提供一致的界面&#xff0c;facade 提供了一高层接口&#xff0c;这个接口使得子系统更容易使用。属于结构型模式…

数据结构的概念大合集06(树和二叉树)

概念大合集06 1、树1.1 树的相关定义1.2 树的基本运算1.3 树的基本术语1.3.1 结点的度&#xff0c;树的度1.3.2 分支结点&#xff0c;叶子节点1.3.3 路径&#xff0c;路径长度1.3.4 孩子结点&#xff0c;双亲结点&#xff0c;兄弟结点1.3.5 结点层次&#xff0c;树的高度1.3.6 …

sentinel中StatisticSlot数据采集的原理

StatisticSlot数据采集的原理 时间窗口 固定窗口 在固定的时间窗口内&#xff0c;可以允许固定数量的请求进入&#xff1b;超过数量就拒绝或者排队&#xff0c;等下一个时间段进入, 如下图 时间窗长度划分为1秒 单个时间窗的请求阈值为3 上述存在一个问题, 假如9:18:04:…

C语言 数组指针 指针数组

指针数组 什么是指针数组&#xff0c;他是一个数组&#xff0c;数组的元素是指针。但是指针也有多种数据类型&#xff0c;有数组指针、函数指针、整形指针、字符串指针。 现在我就使用函数指针来写代码&#xff0c;也就是函数指针数组的应用代码&#xff1a; #include <s…

基于SpringBoot和Vue的课程作业管理系统的设计与实现

今天要和大家聊的是一款基于SpringBoot和Vue的课程作业管理系统的设计与实现。 &#xff01;&#xff01;&#xff01; 有需要的小伙伴可以通过文章末尾名片咨询我哦&#xff01;&#xff01;&#xff01; &#x1f495;&#x1f495;作者&#xff1a;李同学 &#x1f495;&am…

权限提升-Windows权限提升篇数据库篇MYSQLMSSQLORACLE自动化项目

知识点 1、Web到Win-数据库提权-MSSQL 2、Web到Win-数据库提权-MYSQL 3、Web到Win-数据库提权-Oracle 章节点&#xff1a; 1、Web权限提升及转移 2、系统权限提升及转移 3、宿主权限提升及转移 4、域控权限提升及转移 基础点 0、为什么我们要学习权限提升转移技术&#xff1…

ST表和并查集【2024蓝桥杯0基础】-学习笔记

文章目录 ST表-用于优化RMQ问题状态分析例题分析代码复现 并查集例题分析1代码复现 例题分析2状态分析代码复现 合并并查集的方法启发式合并&#xff1a;按照子树的节点大小按秩合并&#xff1a;按照子树的深度 可撤销并查集带权并查集代码复现 例题分析思路分析 感悟 ST表-用于…

android emulator windows bat启动

android emulator windows bat启动 先上结果 // 模拟器路径 -netspeed full -avd 模拟器名称 C:\Users\name\AppData\Local\Android\Sdk\emulator\emulator.exe -netdelay none -netspeed full -avd Pixel_3a_API_34_extension_level_7_x86_64一般来说 windows 如果不做…

小游戏-扫雷

扫雷大多人都不陌生&#xff0c;是一个益智类的小游戏&#xff0c;那么我们能否用c语言来编写呢&#xff0c; 我们先来分析一下扫雷的运行逻辑&#xff0c; 首先&#xff0c;用户在进来时需要我们给与一个菜单&#xff0c;以供用户选择&#xff0c; 然后我们来完善一下&#…

Mac电脑高清媒体播放器:Movist Pro for mac下载

Movist Pro for mac是一款专为Mac操作系统设计的高清媒体播放器&#xff0c;支持多种常见的媒体格式&#xff0c;包括MKV、AVI、MP4等&#xff0c;能够流畅播放高清视频和音频文件。Movist Pro具有强大的解码能力和优化的渲染引擎&#xff0c;让您享受到更清晰、更流畅的观影体…
最新文章