Ошибка типа: не удается распаковать объект с неитерабельными ответами

#python #django #data-structures

Вопрос:

Я пытаюсь сохранить некоторые данные (полученные из API) в свою базу данных. Список (с именем GetQuestion_response ) был получен из этого API, примерно такой (фактические данные из API намного больше, поэтому я показываю здесь первые 2 элемента списка).:

 GetQuestion_response = [
  {
    "Id":1,
    "GroupId":0,
    "QuestionTitle":"What is your first name?",
    "GroupName":null,
    "QuestionType":"TEXT","IsMappingAvailable":null,"BodyRegion":0,"EnableCalculation":false,
    "Responses":[]
  },
  {
    "Id":2,
    "GroupId":0,
    "QuestionTitle":"And your last name?",
    "GroupName":null,
    "QuestionType":"TEXT","IsMappingAvailable":null,"BodyRegion":0,"EnableCalculation":false,
    "Responses":[
      {'Id': 100, 'ResponseText1': 'aaaa', 'ResponseText2': 'bb', 'IsDeleted': False}
      {'Id': 101, 'ResponseText1': 'zzzz', 'IsDeleted': True}
    ]
  }
]
 

мой models.py :

 class Responses(models.Model):
    Answer_Id = models.IntegerField(primary_key=True)
    QuestionId = models.IntegerField(default=0)
    ResponseText1 = models.CharField(max_length=500, null=True, blank=True)
    ResponseText2 = models.CharField(max_length=500, null=True, blank=True)
    ResponseText3 = models.CharField(max_length=500, null=True, blank=True)
    IsDeleted = models.BooleanField(default=False)


class GetQuestion_API(models.Model):
    Question_Id = models.IntegerField(primary_key=True)
    GroupId = models.IntegerField(default=0)
    QuestionTitle = models.TextField()
    GroupName = models.CharField(max_length=500, null=True, blank=True)
    QuestionChoice = [
        ('TEXT', 'TEXT'),
        ('BUTTON', 'BUTTON'),
        ('NUMBER', 'NUMBER')
    ]
    QuestionType = models.CharField(max_length=50, choices=QuestionChoice, default='TEXT', null=True, blank=True)
    IsMappingAvailable = models.CharField(max_length=500, null=True, blank=True)
    BodyRegion = models.CharField(max_length=200, null=True, blank=True)
    EnableCalculation = models.BooleanField(default=False)
    Responses = models.ForeignKey(Responses, on_delete=models.CASCADE, related_name="QuestionReletedResponses", null=True, blank=True)
 

В моем views.py :

 for i in GetQuestion_response:
        this_Id = i['Id']
        this_GroupId = i['GroupId']
        this_QuestionTitle = i['QuestionTitle']
        this_GroupName = i['GroupName']
        this_QuestionType = i['QuestionType']
        this_IsMappingAvailable = i['IsMappingAvailable']
        this_BodyRegion = i['BodyRegion']
        this_EnableCalculation = i['EnableCalculation']


        GetQuestion_API_obj = GetQuestion_API.objects.create(
            Question_Id = this_Id,
            GroupId = this_GroupId,
            QuestionTitle = this_QuestionTitle,
            GroupName = this_GroupName,
            QuestionType = this_QuestionType,
            IsMappingAvailable = this_IsMappingAvailable,
            BodyRegion = this_BodyRegion,
            EnableCalculation = this_EnableCalculation,
        )

        #Creating Response Object Under question
        for j in i['Responses']:
            if j['Id'] is not None:
                Responses_Id = j['Id']
            if j['ResponseText1'] is not None:
                Responses_ResponseText1 = j['ResponseText1']
            else:
                Responses_ResponseText1 = None
            if j['ResponseText2'] is not None:
                Responses_ResponseText2 = j['ResponseText2']
            else:
                Responses_ResponseText2 = None
            if j['ResponseText3'] is not None:
                Responses_ResponseText3 = j['ResponseText3']
            else:
                Responses_ResponseText3 = None
            if j['IsDeleted'] is not None:
                Responses_IsDeleted = j['IsDeleted']

            Responses_obj, created = Responses.objects.create(
                Answer_Id = Responses_Id,
                QuestionId = this_Id,
                ResponseText1 = Responses_ResponseText1,
                ResponseText2 = Responses_ResponseText2,
                ResponseText3 = Responses_ResponseText3,
                IsDeleted = Responses_IsDeleted,
            )
            if created:
                Responses_obj.save()
                GetQuestion_API_obj.Responses_set.add(Responses_obj)
        if created:
            GetQuestion_API_obj.save()
 

Но, к сожалению, в этом коде содержатся такие views.py ошибки, как:

 TypeError: cannot unpack non-iterable Responses object
 

Когда я пытаюсь запустить основной цикл в диапазоне 5 (взяв первые пять элементов списка), он работает отлично. Но это приводит к этой ошибке, когда я запускаю цикл по всему GetQuestion_response списку, содержащему все элементы. Пожалуйста, посоветуйте мне, как я могу решить эту проблему?

Комментарии:

1. Responses.objects.create возвращает созданный Responses экземпляр, он не возвращает кортеж со вторым флагом «создано». Вы хотели использовать Responses.objects.get_or_create ?

2. А также почему вы устанавливаете отношения с помощью IntegerField s ( QuestionId )? Вот для чего предназначено поле ForeignKey . Также, пожалуйста, используйте классы форм / сериализатора (см. Django Rest Framework ), а не анализируйте все это вручную в представлениях…

3. @IainShelvington извините за мою ошибку, на самом деле первые 2 элемента списка имеют пустой Response экземпляр, но все остальные-нет. Я обновил его, пожалуйста, проверьте список еще раз.

4. Я говорю об этой строке Responses_obj, created = Responses.objects.create( , это ваша проблема

5. Непосредственно из документации, которую я связал выше: » Если вам нужно создать связь с моделью, которая еще не определена, вы можете использовать имя модели, а не сам объект модели «, следовательно, это будет просто models.ForeignKey('GetQuestion_API', on_delete=models.CASCADE) . Также GetQuestion_API не является отличным именем для модели (в названии есть глагол «получить»), просто Question было бы лучше? Я бы посоветовал вам провести рефакторинг всего вашего кода, вы, похоже, усложняете себе задачу тем, как вы все написали.