post_generation с фабричным мальчиком дает ManyRelatedManager, когда я хотел список

Я явно тупица, я признаю это в самом начале. Я использую следующую фабрику

class DataSheetFactory(factory.DjangoModelFactory):

    class Meta:
        model = models.myModel
        django_get_or_create = ('key_field',)

    key_field = factory.Sequence(lambda n: n)
    ... <additional fields>
    @factory.post_generation
    def product_contributors(self, create, extracted, **kwargs):
        if not create:
             return
        if extracted:
            for person in extracted:
                self.product_contributors.add(person)

Когда я создаю это с помощью PDS=DataSheetFactory(product_contributors= (<tuple of users>)), я ожидаю список пользователей в поле product_contributors, но вместо этого получаю django.db.models.fields.related.ManyRelatedManager, поэтому тесты не будут работать. Что я должен был делать, следуя «Общим рецептам» здесь?

Просто чтобы уточнить, я спрашиваю, как использовать factory boy для создания списка пользователей в поле модели «многие ко многим». Я попробовал то, что было предложено в документах, и я получил ManyRelatedManager, а не список, поэтому factory_boy создает непригодные для использования экземпляры.


person David Boshton    schedule 28.10.2014    source источник
comment
Что-то тут не понятно. product_contributors не может быть одновременно и методом, и списком, для которого вы вызываете add.   -  person Daniel Roseman    schedule 28.10.2014
comment
@DanielRoseman это сбивает с толку, потому что магия в factoryboy означает, что на самом деле это не метод экземпляра, а self здесь на самом деле экземпляр модели Django, а не фабрики. Я обычно называю этот kwarg obj вместо self в своем коде.   -  person Anentropic    schedule 28.10.2014
comment
@DavidBoshton нормально получать ManyRelatedManager при доступе к полю «многие ко многим» в экземпляре модели Django. если вы хотите, чтобы связанные объекты отображались в виде списка, вам нужно сделать PDS.product_contributors.all() (это будет работать, только если вы используете стратегию create, а не build, поскольку это запрос к базе данных)   -  person Anentropic    schedule 28.10.2014
comment
Итак, как мне создать экземпляр моей модели с этим полем, представляющим собой список элементов, которые я могу просто подключить к своему коду? Мой код ожидает, что это поле будет списком пользователей, а не ManyRelatedManager   -  person David Boshton    schedule 28.10.2014
comment
@DavidBoshton звучит так, будто проблема в вашем коде. Вы получите список, выполнив .all() в менеджере.   -  person Daniel Roseman    schedule 28.10.2014
comment
@ Анэнтропический ах, ладно, честно. Похоже, что в коде OP отсутствует соответствующий декоратор, не знаю, имеет ли это значение.   -  person Daniel Roseman    schedule 28.10.2014
comment
странно хотеть, чтобы ваши экземпляры модели, созданные на заводе, имели атрибут, которого нет в ваших экземплярах модели, не созданных на заводе... Я имею в виду, если ваш другой код ожидает, что это поле будет списком пользователей, возможно, ваш другой код неверен , не завод   -  person Anentropic    schedule 28.10.2014
comment
@Anentropic Это поле в модели. Это поле «многие ко многим», и я понимаю из документов, что вы используете инструмент postgeneration, как указано. Если я хочу добавить группу пользователей в это поле, мне нужно сделать это после создания исходного экземпляра. Итак, как мне заполнить это поле в factory_boy?   -  person David Boshton    schedule 28.10.2014
comment
@DavidBoshton, если это поле модели «многие ко многим», то вы правильно его заполняете на своей фабрике, это ваш другой код, который неправильно ожидает список   -  person Anentropic    schedule 28.10.2014
comment
О да. Теперь я понимаю. Я впервые столкнулся с одним из них и впервые использовал модели с ManyToMany. Спасибо, @Anentropic.   -  person David Boshton    schedule 28.10.2014


Ответы (1)


Как указывалось выше, ваша проблема возникает из-за магии, которую я вложил в factory_boy: self в @post_generation не является экземпляром factory, а только что сгенерированным фактическим объектом.

Таким образом, product_contributors действительно является экземпляром «RelatedManager» Django, вы можете получить доступ к элементам с помощью:

datasheet = DataSheetFactory()
contributors = datasheet.product_contributors.all()
person Xelnor    schedule 29.10.2014