现在支持Django REST Framework 3.0+
动态字段,请参阅http://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields - 这种方法定义了序列化程序中的所有字段,然后允许您有选择地删除您不想要的那些。
或者你也可以为模型序列化器做这样的事情,你在序列化器初始化中弄乱了 Meta.fields:
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('code',)
def __init__(self, *args, **kwargs):
if SHOW_CLASSIFICATION: # add logic here for optional viewing
self.Meta.fields = list(self.Meta.fields)
self.Meta.fields.append('classification')
super(ProductSerializer, self).__init__(*args, **kwargs)
你必须问汤姆这是否是“正确的方式”,因为它可能不符合长期计划。
Django REST Framework < 3.0
试试这样的:
class ProductSerializer(serializers.Serializer):
...
classification = serializers.SerializerMethodField('get_classification')
def get_classification(self, obj):
return getattr(obj, 'classification', None)
多个序列化器
另一种方法是创建具有不同字段集的多个序列化程序。一个序列化器继承自另一个并添加额外的字段。然后您可以使用该get_serializer_class
方法在视图中选择适当的序列化程序。这是一个实际示例,说明如果用户对象与请求用户相同,我如何使用这种方法调用不同的序列化程序来呈现不同的用户数据。
def get_serializer_class(self):
""" An authenticated user looking at their own user object gets more data """
if self.get_object() == self.request.user:
return SelfUserSerializer
return UserSerializer
从表示中删除字段
我在安全上下文中使用的另一种方法是删除to_representation
方法中的字段。定义一个方法,如
def remove_fields_from_representation(self, representation, remove_fields):
""" Removes fields from representation of instance. Call from
.to_representation() to apply field-level security.
* remove_fields: a list of fields to remove
"""
for remove_field in remove_fields:
try:
representation.pop(remove_field)
except KeyError:
# Ignore missing key -- a child serializer could inherit a "to_representation" method
# from its parent serializer that applies security to a field not present on
# the child serializer.
pass
然后在您的序列化程序中,调用该方法
def to_representation(self, instance):
""" Apply field level security by removing fields for unauthorized users"""
representation = super(ProductSerializer, self).to_representation(instance)
if not permission_granted: # REPLACE WITH PERMISSION LOGIC
remove_fields = ('classification', )
self.remove_fields_from_representation(representation, remove_fields)
return representation
这种方法简单而灵活,但它的代价是序列化有时不显示的字段。但这可能没关系。