forked from erp-dev/erp
fin
This commit is contained in:
171
api_core/serializers.py
Normal file
171
api_core/serializers.py
Normal file
@@ -0,0 +1,171 @@
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user