У меня есть типичная модель реляционной базы данных, изложенная в Django, где типичная модель содержит некоторые ForeignKeys
, некоторые ManyToManyFields
и некоторые поля, которые расширяют Django DateTimeField
.
Я хочу сохранить данные, которые я получаю в формате JSON (не flat) из внешнего api. Я не хочу, чтобы данные сохранялись в соответствующих таблицах (а не всей строке 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()
теперь мне обычно приходится сохранять json-строковые данные, которые я получаю из внешней api (secret ninja api) в эту модель, 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 в базе данных, не кодируя вышеуказанную логику несколько раз, что было бы самым элегантным подходом, который вы бы предложить?
Спасибо всем за чтение длинного сообщения,