Django Rest Framework - 如何在 ModelSerializer 中添加自定义字段

     2023-02-23     171

关键词:

【中文标题】Django Rest Framework - 如何在 ModelSerializer 中添加自定义字段【英文标题】:Django Rest Framework - How to add custom field in ModelSerializer 【发布时间】:2013-01-13 01:51:09 【问题描述】:

我创建了一个ModelSerializer 并想添加一个不属于我的模型的自定义字段。

我找到了添加额外字段here 的说明,我尝试了以下方法:

customField = CharField(source='my_field')

当我添加这个字段并调用我的validate() 函数时,这个字段不是attr 字典的一部分。 attr 包含指定的所有模型字段,但额外字段除外。所以我无法在覆盖验证中访问此字段,可以吗?

当我像这样将此字段添加到字段列表时:

class Meta:
    model = Account
    fields = ('myfield1', 'myfield2', 'customField')

然后我收到一个错误,因为 customField 不是我的模型的一部分 - 什么是正确的,因为我只想为这个序列化程序添加它。

有没有办法添加自定义字段?

【问题讨论】:

您能否扩展“但是当我的字段不在序列化程序中指定的模型字段列表中时,它不是 validate() attr-dictionary 的一部分。”,我不确定这是不是很清除。 另外,“它抱怨 - 正确 - 我的模型中没有 customField 字段。”,您能否明确说明您看到的异常 - 谢谢! :) 我更新了我的帖子,希望现在更清楚。我只想知道如何添加一个不属于我的模型的字段... How to extend model on serializer level with django-rest-framework Django REST Framework: adding additional field to ModelSerializer的可能重复 【参考方案1】:

事实上,有一个完全不接触模型的解决方案。您可以使用SerializerMethodField,它允许您将任何方法插入序列化程序。

class FooSerializer(ModelSerializer):
    foo = serializers.SerializerMethodField()

    def get_foo(self, obj):
        return "Foo id: %i" % obj.pk

【讨论】:

正如this comment 中提到的OP,他们想要一个可写字段,而SerializerMethodFields 不是【参考方案2】:

你做对了,除了CharField(和其他类型的字段)是用于可写字段的。

在这种情况下,您只需要一个简单的只读字段,因此只需使用:

customField = Field(source='get_absolute_url')

【讨论】:

谢谢,但我想要一个可写字段。我传递了一个标识我的用户的特定用户令牌。但在我的模型中,我有用户而不是令牌。所以我想传递令牌并通过查询将其“转换”为用户对象。 接下来的事情是源需要以模型属性为目标,对吧?就我而言,我没有指向的属性。 我不明白评论的用户/令牌位。但是,如果您想在序列化程序中包含一个字段,该字段在您恢复到模型实例之前被剥离,您可以使用.validate() 方法来删​​除该属性。请参阅:django-rest-framework.org/api-guide/serializers.html#validation 这可以满足您的需求,尽管我并不真正了解用例,或者为什么您想要一个与 只读 绑定的 writable 字段/b> 属性get_absolute_url? 忘记get_absolute_url 我只是从文档中复制并粘贴它。我只想要一个可以在validate() 中访问的普通可写字段。我只是猜想我需要source 属性... 这更有意义。 :) 该值应该被传递以进行验证,所以我会仔细检查您如何实例化序列化程序,以及是否确实提供了该值。【参考方案3】:

...为清楚起见,如果您有以下方式定义的模型方法:

class MyModel(models.Model):
    ...

    def model_method(self):
        return "some_calculated_result"

您可以像这样将调用所述方法的结果添加到您的序列化程序中:

class MyModelSerializer(serializers.ModelSerializer):
    model_method_field = serializers.CharField(source='model_method')

附言由于自定义字段实际上并不是模型中的字段,因此您通常希望将其设为只读,如下所示:

class Meta:
    model = MyModel
    read_only_fields = (
        'model_method_field',
        )

【讨论】:

如果我想让它可写怎么办? @Csaba:您只需要为附加内容编写自定义保存和删除挂钩:请参阅“方法”下的“保存和删除挂钩”(Here)您需要编写自定义perform_create(self, serializer)perform_update(self, serializer)perform_destroy(self, instance)【参考方案4】:

这里回答你的问题。 您应该添加到您的模型帐户:

@property
def my_field(self):
    return None

现在你可以使用了:

customField = CharField(source='my_field')

来源:https://***.com/a/18396622/3220916

【讨论】:

我已经使用了这种方法,但它并不适合为模型添加额外代码以用于仅真正用于特定 API 调用的事物。 你可以为写一个代理模型【参考方案5】:

为了显示self.author.full_name,我收到Field 的错误。它与ReadOnlyField 合作:

class CommentSerializer(serializers.HyperlinkedModelSerializer):
    author_name = ReadOnlyField(source="author.full_name")
    class Meta:
        model = Comment
        fields = ('url', 'content', 'author_name', 'author')

【讨论】:

【参考方案6】:

使用最新版本的 Django Rest Framework,您需要在模型中创建一个方法,并使用您要添加的字段的名称。

class Foo(models.Model):
    . . .
    def foo(self):
        return 'stuff'
    . . .

class FooSerializer(ModelSerializer):
    foo = serializers.ReadOnlyField()

    class Meta:
        model = Foo
        fields = ('foo',)

【讨论】:

【参考方案7】:

我正在寻找一种将可写自定义字段添加到模型序列化程序的解决方案。我找到了这个,这个问题的答案中没有涉及到。

看来您确实需要编写自己的简单序列化器。

class PassThroughSerializer(serializers.Field):
    def to_representation(self, instance):
        # This function is for the direction: Instance -> Dict
        # If you only need this, use a ReadOnlyField, or SerializerField
        return None

    def to_internal_value(self, data):
        # This function is for the direction: Dict -> Instance
        # Here you can manipulate the data if you need to.
        return data

现在您可以使用此 Serializer 将自定义字段添加到 ModelSerializer

class MyModelSerializer(serializers.ModelSerializer)
    my_custom_field = PassThroughSerializer()

    def create(self, validated_data):
        # now the key 'my_custom_field' is available in validated_data
        ...
        return instance

如果模型 MyModel 实际上有一个名为 my_custom_field 的属性但您想忽略它的验证器,这也有效。

【讨论】:

所以如果 my_custom_field 不是 MyModel 的属性,它就不起作用,对吗?我收到错误序列化程序字段可能命名不正确,并且与MyModel 实例上的任何属性或键都不匹配。【参考方案8】:

在这里阅读所有答案后,我的结论是不可能干净地做到这一点。您必须玩弄脏话并做一些像创建 write_only 字段这样的事情,然后覆盖 validateto_representation 方法。这对我有用:

class FooSerializer(ModelSerializer):

    foo = CharField(write_only=True)

    class Meta:
        model = Foo
        fields = ["foo", ...]

    def validate(self, data):
        foo = data.pop("foo", None)
        # Do what you want with your value
        return super().validate(data)

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data["foo"] = whatever_you_want
        return data

【讨论】:

如果你设置了write_only=True,那你为什么还要设置def to_representation?听起来你既想读又想写....

Django Rest Framework api如何为所有人添加身份验证权限

】DjangoRestFrameworkapi如何为所有人添加身份验证权限【英文标题】:DjangoRestFramewrokapihowtoaddAuthecationpermissionforall【发布时间】:2017-01-2108:27:56【问题描述】:我完全按照此处提供的教程进行操作。http://www.django-rest-framework.org/tutoria... 查看详情

Django REST Framework:如何用空字符串替换 null?

】DjangoRESTFramework:如何用空字符串替换null?【英文标题】:DjangoRESTFramework:howtosubstitutenullwithemptystring?【发布时间】:2019-02-0915:46:30【问题描述】:我有一个具有以下ImageField类型的模型:classAttendance(models.Model):face_image=models.Image... 查看详情

如何处理 django-rest-framework 中 url 模式中的外键关系

】如何处理django-rest-framework中url模式中的外键关系【英文标题】:HowdoIhandleforeignkeyrelationshipintheurlpatterninthedjango-rest-framwork【发布时间】:2022-01-0120:08:15【问题描述】:在我的models.py我有以下类:classProject(models.Model):name=models.Char... 查看详情

Django Rest Framework:在 ViewSet 上打开分页(如 ModelViewSet 分页)

】DjangoRestFramework:在ViewSet上打开分页(如ModelViewSet分页)【英文标题】:DjangoRestFramework:turnonpaginationonaViewSet(likeModelViewSetpagination)【发布时间】:2015-10-2511:33:54【问题描述】:我有一个这样的ViewSet来列出用户的数据:classFoo(view... 查看详情

Django Rest Framework - 如何为所有 ModelSerializer 字段创建自定义错误消息?

】DjangoRestFramework-如何为所有ModelSerializer字段创建自定义错误消息?【英文标题】:DjangoRestFramework-howtocreatecustomerrormessagesforallModelSerializerfields?【发布时间】:2015-08-1410:24:52【问题描述】:这是我的serializers.py(我想为内置的User... 查看详情

处理 django rest framework + vue SPA auth

】处理djangorestframework+vueSPAauth【英文标题】:Handlingdjangorestframework+vueSPAauth【发布时间】:2019-02-2013:46:39【问题描述】:对于单页应用程序(当然是使用Vue路由器),我如何才能获得与django为经过身份验证的用户(用于检索用户... 查看详情

Django Rest Framework 和 django Rest Framework simplejwt 两因素身份验证

】DjangoRestFramework和djangoRestFrameworksimplejwt两因素身份验证【英文标题】:DjangoRestFrameworkanddjangorestframeworksimplejwttwofactorauthentication【发布时间】:2021-09-0915:10:10【问题描述】:我将django3.2.4版与DjangoRestFramework结合使用。我还将https:... 查看详情

Django-rest-framework 和 django-rest-framework-jwt APIViews and validation Authorization headers

】Django-rest-framework和django-rest-framework-jwtAPIViewsandvalidationAuthorizationheaders【英文标题】:Django-rest-frameworkanddjango-rest-framework-jwtAPIViewsandvalidationAuthorizationheaders【发布时间】:2019-05-1220:56:08【问题描述】:我正 查看详情

为啥 django-rest-framework 不显示 OneToOneField 数据 - django

】为啥django-rest-framework不显示OneToOneField数据-django【英文标题】:Whydjango-rest-frameworkdoesn\'tdisplayOneToOneFielddata-django为什么django-rest-framework不显示OneToOneField数据-django【发布时间】:2018-02-1616:26:13【问题描述】:我想在我的网站中... 查看详情

在 Django Rest Framework 中使用 APIView 和 viewset 设置路由器

】在DjangoRestFramework中使用APIView和viewset设置路由器【英文标题】:SettinguprouterwithAPIViewandviewsetinDjangoRestFramework【发布时间】:2020-07-2202:22:38【问题描述】:这是我在***上的第一个问题!我是Django新手,正在学习一些教程。我试图... 查看详情

断言错误:Django-rest-Framework

】断言错误:Django-rest-Framework【英文标题】:Assertionerrorat:Django-rest-Framework【发布时间】:2015-02-1313:36:02【问题描述】:我正在使用python3.4、Django1.7.1(书中考虑的版本)、Postgres9.3,我的IDE是Eclipse。我一直在研究“轻量级Django-E... 查看详情

记录对 django-rest-framework 的请求

】记录对django-rest-framework的请求【英文标题】:Loggingrequeststodjango-rest-framework【发布时间】:2013-03-1219:37:12【问题描述】:出于调试目的,我想使用Django的日志记录机制来记录每个“到达”django-rest-framework门口的传入请求。Djagno... 查看详情

Django Rest Framework:非模型服务

】DjangoRestFramework:非模型服务【英文标题】:DjangoRestFramework:Non-modelservice【发布时间】:2014-06-1009:52:43【问题描述】:我一直在使用django-rest-framework来创建与模型一起使用的服务。现在我需要创建一个服务来接收一些数据,对... 查看详情

如何仅使用 django 作为后端并使用 django-rest-framework 发布

】如何仅使用django作为后端并使用django-rest-framework发布【英文标题】:Howtousedjangoonlyabackendandpostwithdjango-rest-framework【发布时间】:2016-11-2712:06:00【问题描述】:我将只使用Django作为后端。前端将使用React完成,没有django模板。我... 查看详情

django-rest-framework 按日期过滤=无

】django-rest-framework按日期过滤=无【英文标题】:django-rest-frameworkfilterbydate=None【发布时间】:2014-02-2611:35:00【问题描述】:我正在使用django-rest-framework和django-filter。我需要检索date属性为None的小部件列表,但无论我尝试什么查询... 查看详情

在 django-rest-framework 中插入 django-allauth 作为端点

】在django-rest-framework中插入django-allauth作为端点【英文标题】:Plugindjango-allauthasendpointindjango-rest-framework【发布时间】:2013-07-2513:43:42【问题描述】:我在我的网站上使用django-allauth进行社交登录。我还有一个由django-rest-framework提... 查看详情

扩展 django 用户 django-rest_framework 给了我 KeyError

】扩展django用户django-rest_framework给了我KeyError【英文标题】:ExtendingdjangoUserdjango-rest_frameworkgivesmeKeyError【发布时间】:2017-02-1719:01:52【问题描述】:我是djangorest_framework的新手,并且有问题,我已经根据django文档扩展了auth_user,... 查看详情

在 django-rest-framework-jwt 中存储超过默认信息

】在django-rest-framework-jwt中存储超过默认信息【英文标题】:Storemorethandefaultinformationindjango-rest-framework-jwt【发布时间】:2016-05-1607:55:53【问题描述】:我正在使用Django1.8版并使用django-rest-framework-jwt进行身份验证。认证完成后,我... 查看详情