系统角色配置需要设置的接口
用户可以绑定多个角色,角色对应有多个路由权限。用户绑定角色后,可以访问当前角色下的各个api路由和菜单路由。
- 用户注册时设置用户角色
- 修改用户角色(同时对应用户可以访问的路由将会同步变更)
- 添加修改用户角色
- 添加url路由和菜单路由
- 给角色添加或修改路由
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.pypath("userregistry/", UserRegisterView.as_view(), name="userregistry")
## views.py
class UserRegisterView(GenericAPIView):# 注册接口,局部禁用用户验证和权限authentication_classes = ()permission_classes = ()serializer_class = RegisterSerializerdef post(self, request, *args, **kwargs):res = self.get_serializer(data=request.data)res.is_valid(raise_exception=True)data = res.validated_datareturn 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'] = Falseattrs['is_active'] = True# 将用户信息保存到数据库中user = User.objects.create(**attrs)# 为其设置角色为普通用户,2 在表中设置的是普通用户UserRole.objects.create(**{'user_id': user.id, 'role_id': 2})if user:# 签发tokenrefresh = TokenObtainPairSerializer.get_token(user)data = {'code': 100,'message': '登录成功','username': user.username,'refresh': str(refresh),'access': str(refresh.access_token),}return dataelse: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_namereturn role_nameclass Meta:model = UserRolefields = '__all__'
## urls.py
from rest_framework import routers
from systemauth import views as system_viewsrouter = 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_namedef __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 = Rolefields = '__all__'
## urls.py
router.register(r'role', system_views.RoleView, basename='role')
## views.py
class RoleView(ModelViewSet):serializer_class = RoleSerializerqueryset = 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 = Accessfields = '__all__'
## views.py
class AccessConfigView(ModelViewSet):serializer_class = AccessSerializerqueryset = 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 valuedef 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).nameclass Meta:model = RoleAccessfields = '__all__'
## views.py
class RoleAccessViewSet(ModelViewSet):serializer_class = ReleAccessSerializerqueryset = 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')