我有很多类似的字段应该以类似的方式创建。
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
is_friend = serializers.SerializerMethodField('get_is_friend')
# ...
def get_is_friend(self, obj):
user = self.context['request'].user
return user.id in obj.friend_list
# ...
class Meta:
fields = (
'is_friend',
# ...
)
目前我有一个装饰者,它创造了我所需要的一切,除了创建SerializerMethodField
。
def additional_fields_decorator(cls):
relation_methods = (
{
'name': 'is_friend',
'field_name': 'friends',
},
# ...
)
def relation_method_factory(field_name):
def wrapper(self, obj):
user = self.context['request'].user
return user.id in getattr(obj, field_name)
return wrapper
for method in relation_methods:
name = method['name']
name_getter = 'get_{0}'.format(name)
setattr(cls, name_getter, relation_method_factory(method['field_name']))
cls.Meta.fields += (name,)
# following line fails
setattr(cls, name, serializers.SerializerMethodField(name_getter))
return cls
@additional_fields_decorator
class UserSerializer(serializers.ModelSerializer):
pass
谁知道为什么无法在Serializer类之外创建SerializerMethodField
?
答案 0 :(得分:0)
当DRF处理您的UserSerializer
课程时,它会在课程范围内查找SerializerMethodField
。因此,当您在类之外声明方法时,它将无法看到它。
答案 1 :(得分:0)
我最近遇到了类似的问题,我认为您可以通过使用内置类型的方法动态创建序列化程序类来动态添加SerializerMethodField
。像这样:
def generate_serializer(new_field):
all_fields = ['field1', 'field2', new_field]
class Meta:
model = Model
fields = all_fields
def generate_new_field_method(key):
def get_new_field(self, instance):
# some logic based on field name
pass
return get_new_field
dct = {
'new_field': serializers.SerializerMethodField(),
'get_new_field': generate_new_field_method(new_field),
'Meta': Meta,
}
return type('DynamicSerializer', (serializers.ModelSerializer,), dct)
以上示例动态添加了一个字段,但您可以轻松地对其进行修改以添加字段列表。