DRF:如何在使用深度选项的序列化程序中隐藏密码?
DRF: How to hide the password in serializers that use the depth option?
我正在为 User
模型使用以下序列化程序,但是当我使用深度处理外键时,密码显示在 User
对象中。
用户序列化器:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
read_only_fields = ('is_active', 'is_staff', 'is_superuser',)
exclude = ('password', )
extra_kwargs = {'password': {'write_only': True, 'min_length': 4}}
在下面的序列化器中一切正常:
class AuditSerializer(serializers.ModelSerializer):
def __init__(self, instance=None, **kwargs):
if instance:
setattr(self.Meta, 'depth', 10)
else:
setattr(self.Meta, 'depth', 0)
super(AuditSerializer, self).__init__(instance, **kwargs)
initiator = UserSerializer(read_only=True)
class Meta:
model = Audit
fields = ['id', 'initiator']
read_only_fields = ['id', 'initiator']
depth = 0
但在下面与之前model/serializer有关的密码问题:
class AuditAttachmentSerializer(serializers.ModelSerializer):
def __init__(self, instance=None, **kwargs):
if instance:
setattr(self.Meta, 'depth', 10)
else:
setattr(self.Meta, 'depth', 0)
super(AuditAttachmentSerializer, self).__init__(instance, **kwargs)
class Meta:
model = AuditAttachment
fields = ['id', 'audit']
read_only_fields = ['id']
depth = 0
我把__init__
方法删掉改成了下面的解决方法
我在使用 depth
元属性时遇到了同样的问题。 password
被集成到序列化数据中。
第一个解)
根据@JPG 对原始 post 的评论,我使用了 to_representation()
方法,效果非常好!
我已经结束了与我的用户模型相关的序列化程序的这段代码:
from django.contrib.auth.models import Group
from rest_framework import serializers
class BaseGroupSerializer(serializers.ModelSerializer):
class Meta:
model = Group
depth = 1
fields = (
'id',
'name',
'user_set',
)
def to_representation(self, instance):
response = super().to_representation(instance)
for user in response.get("user_set"):
user.pop("password", None)
return response
它只是弹出我组中每个用户的密码字段。
第二个解)
另一个简单的解决方案是直接引用 UserSerializer,您在其中明确排除了密码 exclude = ('password',)
(或不包括它)。
在我的情况下,结果会是这样的:
from django.contrib.auth.models import Group
from rest_framework import serializers
from ..serializers.base_user_serializer import BaseUserSerializer
class BaseGroupSerializer(serializers.ModelSerializer):
user_set = BaseUserSerializer(many=True) # <------
class Meta:
model = Group
depth = 1
fields = (
'id',
'name',
'user_set',
)
与 BaseUserSerializer
保持原样:
from rest_framework import serializers
from ..models.base_user import User
class BaseUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
depth = 1
fields = (
'id',
'username',
'email',
'first_name',
'last_name',
'full_name',
'full_identification',
'is_active',
'groups',
# 'password' is omitted here
)
两种方式都行。第二种方法的唯一问题是,在某些情况下,如果您还在 BaseUserSerializer
.
中导入此 BaseGroupSerializer
,您将面临循环导入
所以根据你的情况和你对进口的限制,...选择你的解决方案:)
我正在为 User
模型使用以下序列化程序,但是当我使用深度处理外键时,密码显示在 User
对象中。
用户序列化器:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
read_only_fields = ('is_active', 'is_staff', 'is_superuser',)
exclude = ('password', )
extra_kwargs = {'password': {'write_only': True, 'min_length': 4}}
在下面的序列化器中一切正常:
class AuditSerializer(serializers.ModelSerializer):
def __init__(self, instance=None, **kwargs):
if instance:
setattr(self.Meta, 'depth', 10)
else:
setattr(self.Meta, 'depth', 0)
super(AuditSerializer, self).__init__(instance, **kwargs)
initiator = UserSerializer(read_only=True)
class Meta:
model = Audit
fields = ['id', 'initiator']
read_only_fields = ['id', 'initiator']
depth = 0
但在下面与之前model/serializer有关的密码问题:
class AuditAttachmentSerializer(serializers.ModelSerializer):
def __init__(self, instance=None, **kwargs):
if instance:
setattr(self.Meta, 'depth', 10)
else:
setattr(self.Meta, 'depth', 0)
super(AuditAttachmentSerializer, self).__init__(instance, **kwargs)
class Meta:
model = AuditAttachment
fields = ['id', 'audit']
read_only_fields = ['id']
depth = 0
我把__init__
方法删掉改成了下面的解决方法
我在使用 depth
元属性时遇到了同样的问题。 password
被集成到序列化数据中。
第一个解)
根据@JPG 对原始 post 的评论,我使用了 to_representation()
方法,效果非常好!
我已经结束了与我的用户模型相关的序列化程序的这段代码:
from django.contrib.auth.models import Group
from rest_framework import serializers
class BaseGroupSerializer(serializers.ModelSerializer):
class Meta:
model = Group
depth = 1
fields = (
'id',
'name',
'user_set',
)
def to_representation(self, instance):
response = super().to_representation(instance)
for user in response.get("user_set"):
user.pop("password", None)
return response
它只是弹出我组中每个用户的密码字段。
第二个解)
另一个简单的解决方案是直接引用 UserSerializer,您在其中明确排除了密码 exclude = ('password',)
(或不包括它)。
在我的情况下,结果会是这样的:
from django.contrib.auth.models import Group
from rest_framework import serializers
from ..serializers.base_user_serializer import BaseUserSerializer
class BaseGroupSerializer(serializers.ModelSerializer):
user_set = BaseUserSerializer(many=True) # <------
class Meta:
model = Group
depth = 1
fields = (
'id',
'name',
'user_set',
)
与 BaseUserSerializer
保持原样:
from rest_framework import serializers
from ..models.base_user import User
class BaseUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
depth = 1
fields = (
'id',
'username',
'email',
'first_name',
'last_name',
'full_name',
'full_identification',
'is_active',
'groups',
# 'password' is omitted here
)
两种方式都行。第二种方法的唯一问题是,在某些情况下,如果您还在 BaseUserSerializer
.
BaseGroupSerializer
,您将面临循环导入
所以根据你的情况和你对进口的限制,...选择你的解决方案:)