這裏有一些簡單代碼片段我的問題:如何使用django-rest-framework反序列化嵌套的相關JSON數據?
的Django模型:
class Champion(models.Model):
id = models.PositiveIntegerField(primary_key=True)
name = models.CharField(max_length=30)
# spells ([List] through ForeignKey in ChampionSpells)
# passive (through ForeignKey in ChampionPassive)
def __str__(self):
return self.name
class ChampionPassive(models.Model):
champion = models.ForeignKey(Champion, related_name='passive', related_query_name='passive')
description = models.TextField()
name = models.CharField(max_length=30)
class ChampionSpell(models.Model):
champion = models.ForeignKey(Champion, related_name='spells', related_query_name='spell')
cooldownBurn = models.CharField(max_length=40)
costBurn = models.CharField(max_length=40)
costType = models.CharField(max_length=10)
# image (through ForeignKey in ChampionImageInfo)
class SpellImageInfo(models.Model):
spell = models.ForeignKey(ChampionSpell, related_name='image', related_query_name='image')
full = models.CharField(max_length=200)
group = models.CharField(max_length=200)
串行器:
class ChampionPassiveSerializer(serializers.ModelSerializer):
class Meta:
model = ChampionPassive
exclude = ('champion',)
class SpellImageInfoSerializer(serializers.ModelSerializer):
class Meta:
model = SpellImageInfo
exclude = ('spell',)
class ChampionSpellSerializer(serializers.ModelSerializer):
# after adding this field, i get a TypeError
image = SpellImageInfoSerializer()
class Meta:
model = ChampionSpell
exclude = ('champion',)
class ChampionSerializer(serializers.ModelSerializer):
passive = ChampionPassiveSerializer()
spells = ChampionSpellSerializer(many=True)
class Meta:
model = Champion
def create(self, validated_data):
spells_data = validated_data.pop('spells')
passive_data = validated_data.pop('passive')
champion = Champion.objects.create(**validated_data)
for spell_data in spells_data:
spell = ChampionSpell.objects.create(champion=champion, **spell_data)
spell_image_data = spell_data.pop('image')
SpellImageInfo.objects.create(spell=spell, **spell_image_data)
ChampionPassive.objects.create(champion=champion, **passive_data)
return champion
JSON數據進行反序列化:
{
"id": 1,
"name": "Annie",
"spells": [{
"name": "Disintegrate",
"description": "Annie hurls a Mana infused fireball, dealing damage and refunding the Mana cost if it destroys the target.",
"image": {
"full": "Disintegrate.png",
"group": "spell"
},
"cooldownBurn": "4",
"costType": "Mana",
"costBurn": "60\/65\/70\/75\/80"
}, {
"name": "Incinerate",
"description": "Annie casts a blazing cone of fire, dealing damage to all enemies in the area.",
"image": {
"full": "Incinerate.png",
"group": "spell"
},
"cooldownBurn": "8",
"costType": "Mana",
"costBurn": "70\/80\/90\/100\/110"
}],
"passive": {
"name": "Pyromania",
"description": "After casting 4 spells, Annie's next offensive spell will stun the target for a short duration."
}
}
請注意,我沒有影響力ñJSON是如何構造的,因爲我從流行的網絡遊戲「傳奇聯盟」的遊戲api中獲得了這一點。這個例子我簡化了很多,還有更多的字段和深度。
我開始反序列化只有頂層的Champion字段工作正常。比我加入ChampionSpells和ChampionPassive沒有更深層次的東西,這些厚厚的東西也工作得很好。
當我與包括SpellImageInfo到ChampionSpell反序列化添加的第二深度級i得到了以下錯誤:
----------------------------------------------------------------------
File "/home/ubuntu/workspace/lolstatistics/stats/serializers.py", line 111, in create
spell = ChampionSpell.objects.create(champion=champion, **spell_data)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 122, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 399, in create
obj = self.model(**kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 443, in __init__
raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
TypeError: 'image' is an invalid keyword argument for this function
----------------------------------------------------------------------
的is_valid()
方法的執行返回True
但是當我調用ChampionSerializer的save()
方法,我得到這個錯誤。我無法弄清楚爲什麼,因爲image
絕對是ChampionSpell
型號通過SpellImageInfo
內的ForeignKey字段。對於低一級的級別(離開SpellImageInfo),它工作正常。
有沒有人對此有解決方案或解釋?
謝謝您的回答。可悲的是,它並沒有幫助我很多,因爲我需要首先驗證數據(根據數據庫字段),而不是反序列化到我的django模型的對象中,以將其存儲在數據庫中。轉換爲字典是,我已經做了,然後將它傳遞給我的序列化程序。但好消息是,我解決了這個問題,現在它運作良好。我會盡快提供答案,自己回答這個問題。 – trixn