如何在Django REST Framework ModelSerializer中读写用户权限字段
解决方案
要实现创建用户时接收权限ID数组、返回时展示权限详细信息的需求,你可以通过以下步骤修改代码:
1. 定义权限序列化器
先创建一个专门序列化权限详情的Serializer,用来格式化返回的权限数据:
from django.contrib.auth.models import Permission from rest_framework import serializers from django.contrib.auth.models import AbstractUser class PermissionSerializer(serializers.ModelSerializer): # 将content_type对象转换为名称字符串(如"account") content_type = serializers.StringRelatedField() class Meta: model = Permission fields = ["id", "name", "codename", "content_type"]
2. 修改用户序列化器
调整UserSerializer,分别处理写入时的权限ID接收和读取时的权限详情返回:
class UserSerializer(serializers.ModelSerializer): # 写入专用:接收权限ID数组,仅用于创建/更新时 user_permissions = serializers.ListField( child=serializers.IntegerField(), write_only=True, required=False ) class Meta: model = AbstractUser fields = "__all__" extra_kwargs = { "password": {"write_only": True}, # 标记默认的user_permissions为只读,避免和自定义字段冲突 "user_permissions": {"read_only": True} } def create(self, validated_data): # 取出请求中的权限ID列表,默认空数组 permission_ids = validated_data.pop("user_permissions", []) # 取出密码并加密存储 password = validated_data.pop("password") # 创建用户实例并设置密码 user = AbstractUser(**validated_data) user.set_password(password) user.save() # 批量添加权限 if permission_ids: user.user_permissions.add(*permission_ids) return user def to_representation(self, instance): # 重写序列化逻辑,替换user_permissions为详细信息 representation = super().to_representation(instance) representation["user_permissions"] = PermissionSerializer( instance.user_permissions.all(), many=True ).data return representation
3. 视图无需额外修改
你的RegistrationView保持现有代码即可,序列化器会自动处理请求和响应的转换。
关键逻辑说明
- 写入处理:自定义的
user_permissions字段为write_only类型,仅接收ID数组,不会在响应中返回。 - 读取处理:通过
to_representation方法,将用户关联的权限数据用PermissionSerializer序列化后替换原字段,返回完整的权限详情。 - 密码安全:手动调用
set_password确保密码加密存储,避免明文保存风险。
内容的提问来源于stack exchange,提问作者Lokesh Sahu
相关产品推荐
相关产品推荐

