我在Django中有一个典型的关系数据库模型,其中一个典型的模型包含一些ForeignKeys
、一些ManyToManyFields
,以及一些扩展Django的DateTimeField
的字段。
我想保存从外部api接收到的JSON格式(不是平面格式)的数据。我不希望数据保存到相应的表中(而不是整个json字符串保存到一个字段中)。要做到这一点,最干净、最简单的方法是什么?是否有使此任务更简单的库?
这里有一个例子来澄清我的问题
型号-
class NinjaData(models.Model):
id = models.IntegerField(primary_key=True, unique=True)
name = models.CharField(max_length=60)
birthdatetime = MyDateTimeField(null=True)
deathdatetime = MyDatetimeField(null=True)
skills = models.ManyToManyField(Skills, null=True)
weapons = models.ManyToManyField(Weapons, null=True)
master = models.ForeignKey(Master, null=True)
class Skills(models.Model):
id = models.IntegerField(primary_key=True, unique=True)
name = models.CharField(max_length=60)
difficulty = models.IntegerField(null=True)
class Weapons(models.Model):
id = models.IntegerField(primary_key=True, unique=True)
name = models.CharField(max_length=60)
weight = models.FloatField(null=True)
class Master(models.Model):
id = models.IntegerField(primary_key=True, unique=True)
name = models.CharField(max_length=60)
is_awesome = models.NullBooleanField()
现在,我通常需要将从外部api(secret ninja api)获得的json字符串数据保存到这个模型中,json如下所示
JSON-
{
"id":"1234",
"name":"Hitori",
"birthdatetime":"11/05/1999 20:30:00",
"skills":[
{
"id":"3456",
"name":"stealth",
"difficulty":"2"
},
{
"id":"678",
"name":"karate",
"difficulty":"1"
}
],
"weapons":[
{
"id":"878",
"name":"shuriken",
"weight":"0.2"
},
{
"id":"574",
"name":"katana",
"weight":"0.5"
}
],
"master":{
"id":"4",
"name":"Schi fu",
"is_awesome":"true"
}
}
现在处理典型的ManyToManyField的逻辑相当简单
逻辑代码-
data = json.loads(ninja_json)
ninja = NinjaData.objects.create(id=data['id'], name=data['name'])
if 'weapons' in data:
weapons = data['weapons']
for weapon in weapons:
w = Weapons.objects.get_or_create(**weapon) # create a new weapon in Weapon table
ninja.weapons.add(w)
if 'skills' in data:
...
(skipping rest of the code for brevity)
我可以用很多方法
view
函数中编写上述逻辑,该函数完成将json转换为模型实例的所有工作__init__
方法save()
方法create
、get_or_create
、filter
等)中编写此逻辑ManyToManyField
并放在那里我想知道,如果有一种最明显的方法可以将json格式的数据保存到数据库中,而不必多次编码上述逻辑,那么您建议的最优雅的方法是什么?
感谢大家阅读这篇长文章
我不知道您是否熟悉这个术语,但您基本上要做的是从序列化/string格式(在本例中是JSON)反序列化到Python模型对象中。
我不熟悉Python库使用JSON来实现这一点,所以我不推荐/支持任何一个,但是使用诸如“Python”、“反序列化”、“JSON”、“object”和“graph”之类的术语进行搜索似乎可以揭示github上的some Django documentation for serialization和库jsonpickle。
实际上我也有同样的需求,我编写了一个自定义数据库字段来处理它。只需将以下内容保存在项目的Python模块中(例如,在适当的应用程序中保存一个
fields.py
文件),然后导入并使用它:几件事。首先,如果您使用的是South,则需要向它解释自定义字段的工作原理:
其次,虽然我已经做了很多工作来确保这个自定义字段在任何地方都能很好地运行,比如在序列化格式和Python之间来回地运行。有一个地方它不能很好地工作,那就是当它与
manage.py dumpdata
一起使用时,它将Python合并为一个字符串,而不是将其转储为JSON,这不是您想要的。我发现这在实际操作中是个小问题。关于writing custom model fields的更多文档。
我断言这是唯一最好和最明显的方法。请注意,我还假设您不需要对这些数据执行查找操作——例如,您将根据其他条件检索记录,这将与它一起提供。如果需要基于JSON中的某些内容进行查找,请确保它是一个真正的SQL字段(并确保它是索引的!)。
在我看来,您需要的代码最干净的地方是在NinjaData模型的自定义管理器上作为一个新的管理器方法(例如从json字符串)。
我不认为你应该重写标准的create、get或create etc方法,因为你做的事情与他们通常做的有点不同,保持他们正常工作是很好的。
更新: 我意识到我可能在某个时候想要这个,所以我编写了代码,并对一个泛型函数进行了简单的测试。因为它递归地遍历并影响其他模型,所以我不再确定它属于Manager方法,而且可能应该是一个独立的helper函数。
相关问题 更多 >
编程相关推荐