Django, добавляющий данные в модель из вложенного json, возвращает ошибку типа: объект ‘NoneType’ не подлежит подписке

#python #json #python-3.x #django #django-models

#python #json #python-3.x #django #django-models

Вопрос:

Я использую сторонний API для получения данных и добавления их в свою базу данных с помощью objects.update_or_create() метода. Эти данные содержат много записей, и некоторые поля в ответе существуют только для определенных записей.

Ниже приведен фрагмент JSON, возвращаемый из API. Однако эти данные присутствуют только для некоторых записей в ответе JSON. Когда я пытаюсь добавить эти данные в свою модель, я получаю следующую ошибку:

 'f_name':               i.get('card_faces')[0].get('name'),
TypeError: 'NoneType' object is not subscriptable
 

Я пытаюсь сделать так, чтобы, если card_faces поле существует, True оно добавлялось в card_face столбец в базе данных, а затем card_faces name в базу данных. Если card_faces не существует, то False добавляется в card_face столбец в базе данных, а последующие поля имеют значение null.

JSON:

 {
  "data": [
    {
      "name": "Emeria Captain"
    },
    {
      "name": "Emeria's Call // Emeria, Shattered Skyclave",
      "card_faces": [
        {
          "object": "card_face",
          "name": "Emeria's Call"
        },
        {
          "object": "card_face",
          "name": "Emeria, Shattered Skyclave"
        }
      ]
    }
  ]
}

 

views.py:

 for i in card_data:
  Card.objects.update_or_create(
    id=i.get('id'),

    defaults={
      'name':       i.get('name'),
      'card_faces': i.get('card_faces'),
      'f_name':     i.get('card_faces')[0].get('name'),
      'b_name':     i.get('card_faces')[1].get('name'),
    }
  )
 

Ответ №1:

Если поле card_faces не существует, результатом .get('card_faces') будет None , для которого вы не сможете вызвать индекс 0

Разбейте вашу строку и вместо этого выполните логическую проверку — это решение предполагает, что если card_faces существует, будут индексы 0 и 1; вы не предоставили достаточно информации, чтобы предположить обратное

 card_faces = i.get('card_faces')
f_name = None
b_name = None

if card_faces:
    f_name = card_faces[0].get('name')
    b_name = card_faces[1].get('name')

defaults = {
  'name':       i.get('name'),
  'card_faces': True if card_faces else False,
  'f_name':     f_name,
  'b_name':     b_name,
}