#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 присваиваю вновь созданную категорию показу. Может быть, я действительно это понимаю. Спасибо.