# -*- 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)
|