title: Most elegant approach for writing JSON data to a relational database using Django Models?
body: <p>I have a typical Relational Database model laid out in Django where a typical model contains some <code>ForeignKeys</code>, some <code>ManyToManyFields</code>, and some fields that extend Django's <code>DateTimeField</code>. </p>
  
  <p>I want to save data that I am receiving in JSON format (not flat) from an external api. I wan't it such that data gets saved to respective tables (not the whole json string to one field). What is the most clean and simple approach to do this? Is there a library available to make this task simpler?</p>
  
  <p>Here's an example to clarify my question,</p>
  
  <p><strong>Models-</strong></p>
  
  <pre><code>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()
  </code></pre>
  
  <p>now, I typically have to save json string data that I obtain from an external api (secret ninja api) into this model, json looks like this</p>
  
  <p><strong>JSON-</strong></p>
  
  <pre><code>{
  "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"
      }
  }
  </code></pre>
  
  <p>now logic for handling a typical ManyToManyField is fairly simple,</p>
  
  <p><strong>logic code -</strong> </p>
  
  <pre><code>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)
  </code></pre>
  
  <p>There are many approaches that i could use,</p>
  
  <ul>
  <li>code above logic in the <code>view</code> function that does all the work of converting json to model instances</li>
  <li>code above logic overriding model's <code>__init__</code> method </li>
  <li>code above logic overriding model's <code>save()</code> method </li>
  <li>create a Manager for each model and code this logic inside each of its methods like <code>create</code>, <code>get_or_create</code>, <code>filter</code> etc. </li>
  <li>extend <code>ManyToManyField</code> and put it there,</li>
  <li>an external library?</li>
  </ul>
  
  <p>I would like to know if there is a <strong>single most obvious way</strong> to save data in this json form to database without coding the above logic multiple times, what would be the most elegant approach that you would suggest?</p>
  
  <p>Thanks all for reading the long post,</p>