系统角色配置需要设置的接口
用户可以绑定多个角色,角色对应有多个路由权限。用户绑定角色后,可以访问当前角色下的各个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.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')