我有一个设置,我需要为现有的javascript数据模型编写一个我不想触摸的API(现在)。 javascript数据的架构与我想要的服务器架构不同。所以我的目标是在将数据发送到API时将我从javascript获得的数据转换为适合我的数据库模型。当从API请求数据时,它应该与javascript的预期数据模型匹配。
我想知道我是否可以使用ModelSerializers做到这一点,如果是的话,哪里是转换数据的正确位置?在视图中?在序列化器中。
我的设置是这样的:
//javascript structure
{
scores: [
{
id: 12,
points: 2
maxpoints: 12
siteuxid: 'EXAMPLE'
},
{ ... }
]
}
//More models in django
{
scores: [
{
id: 12,
points: 2,
question: {
id: 12,
maxpoints: 12,
siteuxid: 'EXAMPLE'
}
},
]
}
有没有任何人可以指出的例子,那是否同样如此?基本上,它是关于在服务器和客户端中使用不同的数据结构并使它们兼容。谷歌没有帮助。
修改 我的第一个问题是我没有在我的Serializer中获得所有发布的数据。当我发布
{
"scores": [{"id":"QFELD_1.1.3.QF2","siteuxid":"VBKM01_VariablenTerme","section":1,"maxpoints":4,"intest":false,"uxid":"ER2","points":0,"value":0,"rawinput":"363"}]
}
到
class UserDataSerializer(serializers.ModelSerializer):
scores = ScoreSerializer(many=True, required=False)
def create(self, validated_data):
print('userDataSerializer validated_data', validated_data)
...
class ScoreSerializer(serializers.ModelSerializer):
id = serializers.CharField(required=False, allow_blank=True, max_length=100)
question = QuestionSerializer(required=False)
class Meta:
model = Score
fields = ('id', 'question', 'points', 'value', 'rawinput', 'state')
我只得到输出
userDataSerializer validated_data {'scores': [OrderedDict([('id', 'QFELD_1.1.3.QF2'), ('points', 0), ('value', 0), ('rawinput', '363')])]}
没有score.maxpoints
等等(因为它不在序列化程序中,但是如何添加呢?要验证数据以便从UserDataSerializer中的发布数据创建正确的问题对象)
答案 0 :(得分:1)
答案是肯定的,您将使用视图修改输入数据,因为您必须在视图将数据发送到序列化程序之前对数据进行这些调整。这是因为您只在经过验证的数据中看到了序列化程序的属性 - 序列化程序忽略了它无法识别的所有属性。
首先,在视图的request.data
方法中更改post
,使其按您的需要进行结构化。
def post(self, request, *args, **kwargs):
request.data['question'] = {
'maxpoints': request.data.pop('maxpoints'),
'siteuxid': request.data.pop('siteuxid'),
}
这应该是您开始使用的全部内容。
但请注意,question
在您的示例中有id: 12
,这很奇怪。如果您尝试与question
对象一起创建score
对象,则该对象应该没有id
。但是,如果问题是现有对象,则不应发送字典,而应仅发送id
。
例如,您应该在输入中发送question: 1
。 DRF ModelSerializer
非常聪明,知道您要保存的score
与question
id = 1
有关。validated_data
在您处理此问题时,请检查序列化程序question
,然后您会看到id = 1
transform()
的实例。魔术!