# -*- coding: utf-8 -*- """ @File : serializers.py @Time : 2023/1/13 11:34 @Author : geekbing @LastEditTime : - @LastEditors : - @Description : 序列化&反序列化 """ from rest_framework import serializers from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from lunarlink.models import LoginLog User = get_user_model() class UserLoginSerializer(serializers.Serializer): """ 用户登录序列化 """ username = serializers.CharField(required=True) password = serializers.CharField(required=True) class UserModelSerializer(serializers.ModelSerializer): """ 访问统计序列化 """ class Meta: model = User fields = [ "id", "is_superuser", "username", "name", "is_staff", "is_active", "groups", ] depth = 1 class LoginLogSerializer(serializers.ModelSerializer): """ 登录日志权限-序列化器 """ class Meta: model = LoginLog fields = "__all__" read_only_fields = ["id"] # 在 UserLoginSerializer 下方添加 class ChangePasswordSerializer(serializers.Serializer): """ 修改密码序列化 """ old_password = serializers.CharField(required=True, max_length=128) new_password = serializers.CharField(required=True, min_length=6, max_length=128) confirm_password = serializers.CharField(required=True, max_length=128) def validate(self, attrs): if attrs['new_password'] != attrs['confirm_password']: raise serializers.ValidationError("两次输入的新密码不一致") return attrs class UserCreateSerializer(serializers.ModelSerializer): """ 创建用户序列化 """ password = serializers.CharField(required=True, min_length=6, max_length=128, write_only=True) confirm_password = serializers.CharField(required=True, max_length=128, write_only=True) groups = serializers.PrimaryKeyRelatedField( many=True, queryset=Group.objects.all(), required=False ) class Meta: model = User fields = ['id', 'username', 'password', 'confirm_password', 'name', 'phone', 'is_staff', 'is_superuser', 'is_active', 'groups', 'show_hosts'] def validate(self, attrs): if attrs['password'] != attrs['confirm_password']: raise serializers.ValidationError("两次输入的密码不一致") return attrs def create(self, validated_data): validated_data.pop('confirm_password') password = validated_data.pop('password') groups = validated_data.pop('groups', None) user = User(**validated_data) user.set_password(password) user.save() if groups: user.groups.set(groups) return user class UserUpdateSerializer(serializers.ModelSerializer): """ 更新用户序列化 """ groups = serializers.PrimaryKeyRelatedField( many=True, queryset=Group.objects.all(), required=False ) class Meta: model = User fields = ['id', 'username', 'name', 'phone', 'is_staff', 'is_superuser', 'is_active', 'groups', 'show_hosts'] def update(self, instance, validated_data): groups = validated_data.pop('groups', None) for attr, value in validated_data.items(): setattr(instance, attr, value) instance.save() if groups is not None: instance.groups.set(groups) return instance class UserDetailSerializer(serializers.ModelSerializer): """ 用户详情序列化 """ groups = serializers.SerializerMethodField() accessible_projects = serializers.SerializerMethodField() status_display = serializers.CharField(source='get_status_display', read_only=True) class Meta: model = User fields = ['id', 'username', 'name', 'phone', 'is_staff', 'is_superuser', 'is_active', 'groups', 'show_hosts', 'date_joined', 'last_login', 'accessible_projects', 'status', 'status_display'] def get_groups(self, obj): return [g.name for g in obj.groups.all()] def get_accessible_projects(self, obj): from lunarlink.models import Project user_groups = obj.groups.all() return list(Project.objects.filter(groups__in=user_groups).distinct().values_list("name", flat=True)) class UserRegisterSerializer(serializers.ModelSerializer): """ 用户注册序列化 """ password = serializers.CharField(required=True, min_length=6, max_length=128, write_only=True) confirm_password = serializers.CharField(required=True, max_length=128, write_only=True) groups = serializers.PrimaryKeyRelatedField( many=True, queryset=Group.objects.all(), required=False ) class Meta: model = User fields = ['username', 'password', 'confirm_password', 'name', 'phone', 'groups'] extra_kwargs = { 'username': {'validators': []}, 'phone': {'validators': []} } def validate_username(self, value): existing_user = User.objects.filter(username=value).first() if existing_user and existing_user.status != 'rejected': raise serializers.ValidationError("用户名已存在") return value def validate_phone(self, value): if value: existing_user = User.objects.filter(phone=value).first() if existing_user and existing_user.status != 'rejected': raise serializers.ValidationError("手机号已存在") return value def validate(self, attrs): if attrs['password'] != attrs['confirm_password']: raise serializers.ValidationError("两次输入的密码不一致") return attrs def create(self, validated_data): validated_data.pop('confirm_password') password = validated_data.pop('password') groups = validated_data.pop('groups', None) username = validated_data['username'] phone = validated_data.get('phone') existing_user = User.objects.filter(username=username).first() if existing_user and existing_user.status == 'rejected': user = existing_user user.name = validated_data.get('name', user.name) user.phone = phone user.set_password(password) user.status = 'pending' user.is_active = False user.save() if groups: user.groups.set(groups) return user if phone: existing_phone_user = User.objects.filter(phone=phone).first() if existing_phone_user and existing_phone_user.status == 'rejected': user = existing_phone_user user.username = username user.name = validated_data.get('name', user.name) user.set_password(password) user.status = 'pending' user.is_active = False user.save() if groups: user.groups.set(groups) return user user = User(**validated_data) user.set_password(password) user.status = 'pending' user.is_active = False user.save() if groups: user.groups.set(groups) return user class UserApprovalSerializer(serializers.Serializer): """ 用户审批序列化 """ action = serializers.ChoiceField(choices=['approve', 'reject']) reason = serializers.CharField(required=False, allow_blank=True, max_length=500)