繁体   English   中英

django-rest-framework 动态添加 SerializerMethodField 到 Serializer

[英]django-rest-framework add SerializerMethodField to Serializer dynamically

我有很多类似的字段应该以类似的方式创建。

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

谁知道为什么SerializerMethodField无法创建串行类以外的?

当 DRF 处理您的UserSerializer类时,它会在类的范围内查找SerializerMethodField 因此,当您在类之外声明该方法时,它不会看到它。

我最近遇到了类似的问题,我认为您可以通过使用类型内置方法动态创建序列化器类来动态添加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)

上面的示例动态添加单个字段,但您可以轻松修改它以添加字段列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM