Как работать с полями ManyToMany при тестировании django-моделей?

<
class TestVolunteeringModels(TestCase):
    def setUp(self) -> None:
        self.test_need = sample_need(title="Need", description="Description")
        self.test_opportunity = sample_opportunity(title="Opportunity", description="Description")
        for i in range(10):
            self.test_category = sample_category(name="Category")
            self.test_need.category = self.test_category
            self.test_opportunity.category = self.test_category

    def tearDown(self) -> None:
        self.test_need.delete()
        self.test_opportunity.delete()

Что приводит меня к этой ошибке:

TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use category.set() instead.

Проблема возникает, когда я использую .set(), как написано в инструкции по трассировке, например так:

self.test_need.category.set(self.test_category)
self.test_opportunity.category.set(self.test_category)

Выдает другую ошибку, которая гласит "TypeError: 'Category' object is not iterable"

Итак, мой вопрос в том, как я могу получить доступ к полю ManyToMany в этом случае, чтобы я мог свободно тестировать его?

Заранее спасибо и всего наилучшего всем людям, которые ответят на этот вопрос!

.set() ожидает итерабельность в качестве аргумента, но аргумент, который вы передаете, self.test_category, не является итерабельным. У вас есть два варианта:

  • Используйте .set([self.test_category,]) вместо .set(self.test_category). Тем самым вы передаете список, который является итерируемым, вместо одного объекта, который не является итерируемым (отсюда и сообщение об ошибке, которое вы получаете).
  • .
  • В качестве альтернативы можно использовать .add(self.test_category). Функция .add() принимает отдельные объекты в качестве позиционных аргументов и добавляет их к любым заранее существующим каталогам.

Вы, вероятно, должны выбрать .set(), потому что это гарантирует, что после его выполнения набор ассоциированных категорий будет именно тем, который вы передадите.

Вернуться на верх