2016-12-23 4 views
0

Я пытаюсь сохранить несколько экземпляров Heat и сохранить их в списке heats, а затем использовал список в качестве bulk_create.Django - TypeError: аргумент int() должен быть строкой или числом, а не 'dict'

В моем models.py

class Animal(models.Model): 

    farm = models.ForeignKey(Farm, related_name='farm_animals', on_delete=models.CASCADE) 
    herd = models.ForeignKey(Herd, related_name='animals', on_delete=models.CASCADE) 

    name = models.CharField(max_length=25) 
    .... 

class Heat(models.Model): 

    # Relationship Fields 
    animal = models.ForeignKey(Animal, related_name='heats', on_delete=models.CASCADE) 

    # Fields 
    .... 

В моем views.py

@transaction.atomic 
def create(self, request): 
    heats = [] 
    for item in request.data: 
     animal = Animal(item['animal']) 
     heat = Heat(item['heat']) 
     heat.animal = animal 

     heats.append(heat) 

    Heat.objects.bulk_create(heats) 

request.data является JSON сериализации. Вот как это выглядит.

[ 
    { 
     "animal" : { 
      "id" : 1, 
      .... 
     }, 
     "heat" : { 
      .... 
     } 
    }, 
    { 
     "animal" : { 
      "id" : 2, 
      .... 
     }, 
     "heat" : { 
      .... 
     } 
    }, 
    { 
     "animal" : { 
      "id" : 3, 
      .... 
     }, 
     "heat" : { 
      .... 
     } 
    } 
] 

Но я получил ошибку: TypeError: int() argument must be a string or a number, not 'dict'


Вот полный отслеживающий:

Traceback (most recent call last): 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\core\handlers\exception.py", line 39, in inner 
    response = get_response(request) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response 
    response = self.process_exception_by_middleware(e, request) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\views\decorators\csrf.py", line 58, in wrapped_view 
    return view_func(*args, **kwargs) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\rest_framework\viewsets.py", line 83, in view 
    return self.dispatch(request, *args, **kwargs) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\rest_framework\views.py", line 477, in dispatch 
    response = self.handle_exception(exc) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\rest_framework\views.py", line 437, in handle_exception 
    self.raise_uncaught_exception(exc) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\rest_framework\views.py", line 474, in dispatch 
    response = handler(request, *args, **kwargs) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\utils\decorators.py", line 185, in inner 
    return func(*args, **kwargs) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\farm_management\heat\views.py", line 188, in create 
    Heat.objects.bulk_create(heats) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\manager.py", line 85, in manager_method 
    return getattr(self.get_queryset(), name)(*args, **kwargs) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\query.py", line 449, in bulk_create 
    self._batched_insert(objs_with_pk, fields, batch_size) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\query.py", line 1068, in _batched_insert 
    self._insert(item, fields=fields, using=self.db) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\query.py", line 1045, in _insert 
    return query.get_compiler(using=using).execute_sql(return_id) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\sql\compiler.py", line 1053, in execute_sql 
    for sql, params in self.as_sql(): 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\sql\compiler.py", line 1006, in as_sql 
    for obj in self.query.objs 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\sql\compiler.py", line 945, in prepare_value 
    value = field.get_db_prep_save(value, connection=self.connection) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\fields\__init__.py", line 755, in get_db_prep_save 
    prepared=False) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\fields\__init__.py", line 938, in get_db_prep_value 
    value = self.get_prep_value(value) 
    File "C:\Users\Web\Desktop\PyDev\Envs\djangular\lib\site-packages\django\db\models\fields\__init__.py", line 946, in get_prep_value 
    return int(value) 
TypeError: int() argument must be a string or a number, not 'dict' 

Я не могу полностью понять ситуацию, так как я новичок в Джанго развития. Пожалуйста помоги.

+0

Не могли бы вы привести пример того, как 'request.data' выглядит? –

+0

уверен, один момент пожалуйста –

+0

Чтобы ответить на ваш вопрос, необходимо знать: 1) поля (с типами) моделей 'Animal' и' Heat'; 2) структура 'request.data'. И наивно я не могу понять, как вы создаете объекты «Heat», не создавая объекты «Animal» раньше, объект «Heat» должен иметь внешний ключ для объекта «Animal» ... – Fomalhaut

ответ

1

Вы должны извлечь из базы данных уже существующих животных, а не создавать новые. И неплохо также вытащить животных «навалом», чтобы повысить производительность.

Код:

@transaction.atomic 
def create(self, request): 
    # Extracting animals 
    animal_id_list = [item['animal']['id'] for item in request.data] 
    animals = Animal.objects.in_bulk(animal_id_list) 
    animals_dict = {animal.id: animal for animal in animals} 

    # Creating heats 
    heats = [] 
    for item in request.data: 
     heat = Heat(**item['heat']) 
     heat.animal = animals_dict[item['animal']['id']] 
     heats.append(heat) 
    Heat.objects.bulk_create(heats) 
+0

Спасибо за ответ, но животное уже существует в базе данных, и я просто хотел создать их записи тепла. –

+0

Чем вы должны извлечь правильное животное из БД. Я отредактирую свой код через некоторое время. – Fomalhaut

+0

Спасибо, друг, я ценю это –

0

Это связано с отношением внешнего ключа между моделями. Если ваша модель имеет название ForeignKey, то ваше data_dict должно иметь поле animal_id. Но django.forms.model_to_dict() возвращает диктофон с полем для животных.
Таким образом, вы не можете сделать MyModel(**model_to_dict(my_instance)); вы должны переименовать поле животных в animal_id

Нечто подобное должно работать:
heat.animal_id = animal.id

+0

Благодарим вас за ответ, который я тестировал. –

+0

все еще не работает, но когда я делаю 'print animal.id', он печатает весь объект со значениями, а не только идентификатором. –

+0

После создания объекта животного сохраните его перед доступом к идентификатору. –

0

В вашем методе create, вы должны пройти item['heat'] как kwargs и спасти скотину используя его в тепле. Например.

@transaction.atomic 
def create(self, request): 
    heats = [] 
    for item in request.data: 
     animal = Animal.objects.get(id=item['animal']['id']) 
     heat = Heat(animal=animal, **item['heat']) 

     heats.append(heat) 

    Heat.objects.bulk_create(heats) 
+0

Не рекомендуется использовать 'animal.save'. Он работает нормально, но он слишком медленный. OP хочет использовать 'bulk_create', чтобы избежать' .save' – Fomalhaut

+0

Не знал, что у OP были животные, уже сохраненные в базе данных. –

+0

это работает даже без doin 'anima.save()', но мне нужно удалить некоторые ненужные данные из контекста животных. –

Смежные вопросы