这不是特定用例的问题,而是我在使用API时体验到的一些问题,特别是使用Django和Django Rest Framework。
几个月前,我为客户的项目维护的API存在问题。
我们假设我们有以下型号:
class Person:
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
然后,相应的序列化器:
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
fields = '__all__'
当然,它对应的ViewSet和路由指向它:
http://localhost:8000/api/v1/persons/
请注意,这是我的API的第一个版本。
此时一切都还好,对吧?
现在,我的客户要求我们需要单独收到人的姓名而不是姓名...
按照惯例,我必须将我的模型改为:
class Person:
full_name = models.CharField(max_length=200)
使用此版本的API有3个不同的客户端(移动应用程序)。显然,我不想更改我的API,而是希望将新方法用于新版本。
但是第一个版本的Serializer与模型相结合,所以此时API的第一个版本已经改变
我希望在下面的答案中看到你们是如何处理Django中的这个问题的,以及我应该采用相同的堆栈为下一个项目采取的方式。
编辑:我的问题是要了解是否更好地将API与模型分离。我已经提出了一个非常基本的例子,但有些情况会使事情变得复杂得多。例如,我需要修改M2M关系以使用through选项,以便向中间表添加更多字段。
答案 0 :(得分:1)
这类问题可被标记为"推荐smth",但无论如何。
首先,您需要使用full_name
字段扩展模型。如果您需要能够从api写入full_name
提供的模型,那么您需要扩展到字段,否则您可以处理property
@property
def full_name(self):
return '{} {}'.format(self.first_name, self.last_name)
然后您还可以在序列化程序中包含字段
class PersonSerializer(serializers.ModelSerializer):
full_name = serializers.CharField() # if you have property
class Meta:
model = Person
fields = '__all__'
由于您将字段名称和序列化程序字段名称匹配,因此您不必担心。
因此,增加一个领域不会打破你的客户并满足你的大客户。