forked from erp-dev/erp
172 lines
5.8 KiB
Python
172 lines
5.8 KiB
Python
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.models import Group, Permission
|
|
from django.db import transaction
|
|
from rest_framework import serializers
|
|
from drf_spectacular.utils import extend_schema_field
|
|
|
|
from basic_info.models import UserProfile
|
|
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class CorePermissionSerializer(serializers.ModelSerializer):
|
|
app_label = serializers.CharField(source="content_type.app_label", read_only=True)
|
|
model = serializers.CharField(source="content_type.model", read_only=True)
|
|
full_code = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Permission
|
|
fields = [
|
|
"id",
|
|
"name",
|
|
"codename",
|
|
"content_type",
|
|
"app_label",
|
|
"model",
|
|
"full_code",
|
|
]
|
|
read_only_fields = fields
|
|
|
|
def get_full_code(self, obj) -> str:
|
|
return f"{obj.content_type.app_label}.{obj.codename}"
|
|
|
|
|
|
class CoreGroupSerializer(serializers.ModelSerializer):
|
|
permissions = serializers.PrimaryKeyRelatedField(
|
|
many=True,
|
|
queryset=Permission.objects.select_related("content_type").all(),
|
|
required=False,
|
|
)
|
|
permission_details = CorePermissionSerializer(
|
|
source="permissions",
|
|
many=True,
|
|
read_only=True,
|
|
)
|
|
|
|
class Meta:
|
|
model = Group
|
|
fields = ["id", "name", "permissions", "permission_details"]
|
|
|
|
|
|
class CoreUserSerializer(serializers.ModelSerializer):
|
|
groups = serializers.PrimaryKeyRelatedField(
|
|
many=True,
|
|
queryset=Group.objects.all(),
|
|
required=False,
|
|
)
|
|
user_permissions = serializers.PrimaryKeyRelatedField(
|
|
many=True,
|
|
queryset=Permission.objects.select_related("content_type").all(),
|
|
required=False,
|
|
)
|
|
password = serializers.CharField(write_only=True, required=False, min_length=6)
|
|
merchant_id = serializers.IntegerField(source="profile.merchant_id", read_only=True)
|
|
employee_id = serializers.IntegerField(source="employee.id", read_only=True)
|
|
employee_name = serializers.CharField(source="employee.name", read_only=True)
|
|
group_details = serializers.SerializerMethodField()
|
|
permission_details = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = User
|
|
fields = [
|
|
"id",
|
|
"username",
|
|
"email",
|
|
"first_name",
|
|
"last_name",
|
|
"is_active",
|
|
"is_staff",
|
|
"is_superuser",
|
|
"last_login",
|
|
"date_joined",
|
|
"merchant_id",
|
|
"employee_id",
|
|
"employee_name",
|
|
"groups",
|
|
"group_details",
|
|
"user_permissions",
|
|
"permission_details",
|
|
"password",
|
|
]
|
|
read_only_fields = [
|
|
"id",
|
|
"last_login",
|
|
"date_joined",
|
|
"merchant_id",
|
|
"employee_id",
|
|
"employee_name",
|
|
"group_details",
|
|
"permission_details",
|
|
]
|
|
|
|
@extend_schema_field(serializers.ListField(child=serializers.DictField()))
|
|
def get_group_details(self, obj) -> list[dict[str, object]]:
|
|
return [{"id": group.id, "name": group.name} for group in obj.groups.all()]
|
|
|
|
@extend_schema_field(CorePermissionSerializer(many=True))
|
|
def get_permission_details(self, obj) -> list[dict[str, object]]:
|
|
permissions = obj.user_permissions.select_related("content_type").all()
|
|
return CorePermissionSerializer(permissions, many=True).data
|
|
|
|
def validate_username(self, value):
|
|
queryset = User.objects.filter(username=value)
|
|
if self.instance is not None:
|
|
queryset = queryset.exclude(pk=self.instance.pk)
|
|
if queryset.exists():
|
|
raise serializers.ValidationError("用户名已存在")
|
|
return value
|
|
|
|
def validate(self, attrs):
|
|
request = self.context.get("request")
|
|
current_user = getattr(request, "user", None)
|
|
target_user = self.instance
|
|
|
|
if current_user is not None and target_user is not None and current_user.pk == target_user.pk:
|
|
if attrs.get("is_active") is False:
|
|
raise serializers.ValidationError({"is_active": "不能停用当前登录用户"})
|
|
if attrs.get("is_superuser") is False:
|
|
raise serializers.ValidationError({"is_superuser": "不能取消当前登录用户的 superuser 权限"})
|
|
|
|
return attrs
|
|
|
|
def create(self, validated_data):
|
|
groups = validated_data.pop("groups", [])
|
|
user_permissions = validated_data.pop("user_permissions", [])
|
|
password = validated_data.pop("password", None)
|
|
merchant = self.context["merchant"]
|
|
|
|
with transaction.atomic():
|
|
user = User(**validated_data)
|
|
if password:
|
|
user.set_password(password)
|
|
else:
|
|
user.set_unusable_password()
|
|
user.save()
|
|
if groups:
|
|
user.groups.set(groups)
|
|
if user_permissions:
|
|
user.user_permissions.set(user_permissions)
|
|
UserProfile.objects.create(user=user, merchant=merchant)
|
|
|
|
return user
|
|
|
|
def update(self, instance, validated_data):
|
|
groups = validated_data.pop("groups", None)
|
|
user_permissions = validated_data.pop("user_permissions", None)
|
|
password = validated_data.pop("password", None)
|
|
|
|
with transaction.atomic():
|
|
for attr, value in validated_data.items():
|
|
setattr(instance, attr, value)
|
|
if password:
|
|
instance.set_password(password)
|
|
instance.save()
|
|
if groups is not None:
|
|
instance.groups.set(groups)
|
|
if user_permissions is not None:
|
|
instance.user_permissions.set(user_permissions)
|
|
|
|
return instance
|
|
|