[英]Django Rest Framework - re-using models logic when deserializing responses in a python client
When developing a REST API using django and django rest framework, it seems to me that there's a step missing at the very end of this chain, especially if you'll design a python client of that API :在使用 django 和 django rest 框架开发 REST API 时,在我看来,这条链的最后缺少一个步骤,特别是如果您要设计该 API 的 python 客户端:
Let me give a simple example.让我举一个简单的例子。 I declare the following django model with a bit of business logic:我声明了以下带有一些业务逻辑的 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 is super powerful when it comes to building the API around that model. DRF 在围绕该模型构建 API 时非常强大。 However, if I call that API from a python client, it seems that the best I can get as a response from that API will be a simple json without all the logic I might have written in my model (in this case, the __repr__
method), and I'll have to navigate through it as such.但是,如果我从 python 客户端调用该 API,似乎我能从该 API 获得的最佳响应将是一个简单的 json,没有我可能在我的模型中编写的所有逻辑(在这种情况下, __repr__
方法),我将不得不像这样浏览它。
Continuing my example, here is the difference with and without a proper deserializer:继续我的例子,这里是有和没有合适的解串器的区别:
# 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)
Is there a clean way to stay DRY and write the logic only once?有没有一种干净的方法来保持 DRY 并且只编写一次逻辑?
I've thought about a couple of options which are not satisfactory in my opinion:我已经考虑了几个在我看来并不令人满意的选择:
One option for you would be to use SerializerMethodField
您的一种选择是使用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})"
Now you should have:现在你应该有:
>> print(api.get(id=3))
{"numberplate": "123ABC", "country_code": "BE", "display": "123ABC (BE)"}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.