Django 如何向ModelSerializer添加方法字段

Django 如何向ModelSerializer添加方法字段,django,django-rest-framework,Django,Django Rest Framework,在SerializerMethodField的DRF文档中,它给出了以下使用示例 class UserSerializer(serializers.ModelSerializer): days_since_joined = serializers.SerializerMethodField() class Meta: model = User def get_days_since_joined(self, obj): return (n

在SerializerMethodField的DRF文档中,它给出了以下使用示例

class UserSerializer(serializers.ModelSerializer):
    days_since_joined = serializers.SerializerMethodField()

    class Meta:
        model = User

    def get_days_since_joined(self, obj):
        return (now() - obj.date_joined).days
不幸的是,它在最新版本的DRF中失败了,因为ModelSerializer希望元数据中出现
字段
排除
。这是一个问题。如果我在
字段
列表中列出方法字段,我会得到一个错误

django.core.exceptions.ImproperlyConfigured: Field name `days_since_joined` is not valid for model `User`.
如果我不包括方法字段,或者如果我使用
fields=“\uuuu all\uuuu”
或者如果我使用
exclude
方法字段,那么序列化数据中就会丢失方法字段

如何在模型序列化程序中包含方法字段

编辑:我发现了一个丑陋的漏洞,允许为自定义模型添加方法字段。您可以向模型添加一个伪属性,然后一切都按预期工作

class MyModel(models.Model):
    field1 = models.IntegerField()
    field2 = models.CharField()
    # more fields

    @property
    def my_method_field(self):
        return None

class MyModelSerializer(serializers.ModelSerializer):
    my_method_field = serializers.SerializerMethodField(method_name='bleh')

    class Meta:
        model = MyModel
        fields = ('field1', 'field2', 'my_method_field')

    def bleh(self, obj):
        return 'Bleh!'
但是为类似的东西向模型添加占位符属性代码不是一个好的实践,这并不能解决使用外部定义的模型(如Django用户模型)这样做的问题


编辑#2我发誓我已经尝试添加排除和字段的所有可能组合。然而,不知何故,第二天当我回到这个问题时,它只是在合理的排除条件下起作用。我将把“空排除”的答案标记为正确答案,并将此作为对人类注意力的反复无常和小精灵的秘密魔法的敬意留在这里。

你试过空排除吗

class UserSerializer(serializers.ModelSerializer):
    days_since_joined = serializers.SerializerMethodField()

    class Meta:
        model = User
        exclude = ()
        #       ^^^^^

    def get_days_since_joined(self, obj):
        return (now() - obj.date_joined).days

您是否尝试过清空
排除

class UserSerializer(serializers.ModelSerializer):
    days_since_joined = serializers.SerializerMethodField()

    class Meta:
        model = User
        exclude = ()
        #       ^^^^^

    def get_days_since_joined(self, obj):
        return (now() - obj.date_joined).days

您能否确认自加入以来您是否获得了
days\u
不存在或加入的
date\u
不存在?要检查的内容是否正确:-方法名称位于Meta.fields中(假设为“foo”)-别忘了添加“foo”SerializerMethodField属性-对于方法本身-确保它是get\u foo而不仅仅是foo。不要使方法_name='foo'和def foo(不能有相同的名称)。你可以使用方法名称,但要确保它是唯一的。你能确认加入后的
days\u是否不存在或
date\u加入后的
days\u
是否不存在吗?检查事项是否正确:-方法名称在Meta.fields中(假设为“foo”)-别忘了添加一个“foo”SerializerMethodField属性-对于方法本身-确保它是get\u foo而不仅仅是foo。不要使方法_name='foo'和def foo(不能有相同的名称)。您可以使用方法名称,但请确保它是唯一的。