Django REST Framework 3.0+
现在支持动态字段,请查看http://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields -- 这种方法定义序列化器中的所有字段,然后允许您选择性地删除不需要的字段。
或者您还可以像这样对模型序列化器进行操作,在序列化器init中混合 Meta.fields:
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('code',)
def __init__(self, *args, **kwargs):
if SHOW_CLASSIFICATION:
self.Meta.fields = list(self.Meta.fields)
self.Meta.fields.append('classification')
super(ProductSerializer, self).__init__(*args, **kwargs)
如果这种方式不符合长期计划,你需要问一下Tom是否认为这是“正确的方式”。
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:
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:
remove_fields = ('classification', )
self.remove_fields_from_representation(representation, remove_fields)
return representation
这种方法直截了当且灵活,但代价是对有时不显示的字段进行序列化。 但那也许没有关系。
None
是可以接受的吗?还是说根本不应该出现这个键? - Tom Christie