Ошибка значения при назначении отношения m2m после сохранения данных — недопустимый литерал для int() с основанием 10: «Музыка»

#python #django #object #model #m2m

#python #django #объект #Модель #m2m

Вопрос:

Я создаю объект «Show» со многими атрибутами. Одним из его атрибутов является «категории», которое представляет собой поле «Многие ко многим», связанное с другим объектом «Категории».

Прежде чем я создам «Шоу» (взяв данные из переданного объекта), я создаю категории, для которых будет назначено это шоу, например:

 for each_category in parsed_podcast.categories:
        Category.objects.get_or_create(title=each_category,
                                        slug=slugify(each_category),
                                        full=each_category,
                                        )
 

Приведенный выше код создает объекты в моей модели категорий, я могу проверить и убедиться, что они есть. Как только они появятся, затем я создаю объект Show с множеством атрибутов, которые я удалил, потому что они не имеют отношения к делу:

 try:
        podcast_instance = Show.objects.get(title=parsed_podcast.title)
except Show.DoesNotExist:
        podcast_instance = Show(title=parsed_podcast.title,
                    slug=slugify(parsed_podcast.title),
                    image_title=parsed_podcast.image_title,
                    image_url=parsed_podcast.image_url,
                    .....
                    )
       podcast_instance.save()

 

Все это работает нормально, пока я не попытаюсь присвоить категорию (из parsed_podcast.categories) вновь созданной категории, созданной на первом шаге, вот так:

 for each_category in parsed_podcast.categories:
            print('The category in the parsed podcast is {}'.format(each_category))
            podcast_instance.categories.add(each_category)
 

Я никогда не могу назначить категорию — она всегда остается в качестве опции, когда я проверяю администратора Django в модели. Я хочу назначить его программно, но я получаю сообщение об ошибке:

 ValueError: invalid literal for int() with base 10: 'Music'
 

Трассировки:

 Traceback (most recent call last):
  File "podcasts.py", line 211, in <module>
    podcast_s()
  File "populate.py", line 205, in podcast_scrape
    submit(parsed_podcast,podcast_rss)
  File "populate.py", line 118, in submit2
    podcast_instance.categories.add(each_category)

  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelsfieldsrelated_descriptors.py", line 926, in add
    self._add_items(self.source_field_name, self.target_field_name, *objs)
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelsfieldsrelated_descriptors.py", line 1073, in _add_items
    '%s__in' % target_field_name: new_ids,
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelsquery.py", line 844, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelsquery.py", line 862, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelssqlquery.py", line 1263, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelssqlquery.py", line 1287, in _add_q
    split_subq=split_subq,
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelssqlquery.py", line 1225, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelssqlquery.py", line 1096, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelslookups.py", line 20, in __init__
    self.rhs = self.get_prep_lookup()
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelsfieldsrelated_lookups.py", line 59, in get_prep_lookup
    self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelsfieldsrelated_lookups.py", line 59, in <listcomp>
    self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
  File "C:UserspAnaconda3envsmyDjangoEnvlibsite-packagesdjangodbmodelsfields__init__.py", line 965, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: 'Music'
 

У меня такое чувство, что в моем parsed_podcast.categories не всегда одно и то же. Существует ли эффективный метод очистки этих данных каждый раз? Или есть другая проблема.

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

1. Это не имеет смысла. Вы не можете передать туда строку. Вам нужен экземпляр категории, который вы создали на первом шаге. Я не уверен, почему у вас есть отдельные циклы — почему вы не можете сделать все это за один шаг? Я думаю, вам нужно показать, как эти три фрагмента сочетаются друг с другом; покажите полный код в контексте.

2. Мой друг, расслабься. Хотя, возможно, вы привыкли к этим вещам, OP является новым и пытается понять, как это можно сделать, поскольку он не очень хорошо знает, как работать со многими ко многим.

Ответ №1:

Проблема в том, что вы пытаетесь передать строку, которую вы проанализировали, когда вы должны либо передать pk объект, либо category объект.

При создании categories используйте созданный объект.

 for each_category in parsed_podcast.categories:
       category, created = Category.objects.get_or_create(title=each_category,
                                        slug=slugify(each_category),
                                        full=each_category,
                                        )
       print('The category in the parsed podcast is {}'.format(each_category))
       podcast_instance.categories.add(category)
 

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

1. Эй, спасибо — значит, это сработало. Я не совсем уверен, что понимаю, как это сделать. Там, где у вас есть «категория, созданная», я не совсем понимаю, что это делает… Итак, первая переменная «категория» — это фактический объект? А второй — это bool, чтобы увидеть, действительно ли он создал объект или нет…

2. Но я еще не много работал с такой распаковкой кортежей — я совсем новичок. Итак, это распаковка кортежа, и я получаю обратно объект категории, созданный True или False, а затем в этом цикле for присваиваю вновь созданную категорию показу. Может быть, я действительно это понимаю. Спасибо.