繁体   English   中英

Django Rest Framework - 在 python 客户端中反序列化响应时重用模型逻辑

[英]Django Rest Framework - re-using models logic when deserializing responses in a python client

在使用 django 和 django rest 框架开发 REST API 时,在我看来,这条链的最后缺少一个步骤,特别是如果您要设计该 API 的 python 客户端

  • 在 Django 中定义资源模型
  • 使用 DRF 的序列化程序通过 HTTP 发送您的资源
  • 丢失:将您的资源反序列化回 Python 模型

让我举一个简单的例子。 我声明了以下带有一些业务逻辑的 Django 模型:

class Numberplate(models.Model):
    number = models.CharField(max_length=128)
    country_code = models.CharField(max_length=3)

    def __repr__(self):
        return f"{self.number} ({self.country_code})"

DRF 在围绕该模型构建 API 时非常强大。 但是,如果我从 python 客户端调用该 API,似乎我能从该 API 获得的最佳响应将是一个简单的 json,没有我可能在我的模型中编写的所有逻辑(在这种情况下, __repr__方法),我将不得不像这样浏览它。

继续我的例子,这里是有和没有合适的解串器的区别:

# the best we can do without rewriting code:
>> print(api.get(id=3))
{"numberplate": "123ABC", "country_code": "BE"}

# instead of re-using my __repr__, which would be ideal:
>> print(api.get(id=3))
123ABC (BE)

有没有一种干净的方法来保持 DRY 并且只编写一次逻辑?

我已经考虑了几个在我看来并不令人满意的选择:

  • 编写一个 django-model-agnostic Numberplate 类并使您的模型类继承自models.Model和该类
  • 在客户端中导入 django 模型( 像这样

您的一种选择是使用SerializerMethodField

class NumberplateSerializer(serializers.ModelSerializer):
    display = serializers.SerializerMethodField()

    class Meta:
        model = Nameplate
        fields = [..., 'display']

    def get_display(self, obj):
        return str(obj)
        # Or you can move your business logic here directly.
        # return f"{obj.number} ({obj.country_code})"

现在你应该有:

>> print(api.get(id=3))
{"numberplate": "123ABC", "country_code": "BE", "display": "123ABC (BE)"}

暂无
暂无

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

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