Как создать фабрику Factory-Boy для модели с полем TaggableManager

Как я могу создать поле в Factory-Boy для TaggableManager из django-taggit?

Не работает следующее:

Первый:

class ExperimentFactory(factory.DjangoModelFactory):
    class Meta:
        model = Experiment
        django_get_or_create = ('owner', 'name', 'start_date', 'stop_date', )

    owner = factory.SubFactory(UserFactory)
    name = factory.Sequence(lambda n : 'Experiment %s' % n)

    start_date = fuzzy.FuzzyDate(start_date=datetime.date(2003, 2, 1), 
                                     end_date = datetime.date.today() + timedelta(days=4*52*7+5))

    tags = [u'abc, cde', u'xzy']

Ошибка: TypeError: 'tags' является недопустимым аргументом ключевого слова для этой функции.

Второй: (с factory.post_generation). Итак, вместо последней строки есть

@factory.post_generation
def post_tags(self, create, extracted, **kwargs):
    self.tags = [u'abc, cde', u'xzy']
    # self.save() # This does not have any effects

Я получаю результат от Experiment.objects.get(pk=1).tags []

Для некоторых деталей:

Тестирование объектов в TestCase это:

experiment = ExperimentFactory(owner = self.user)
saved_experiment = Experiment.objects.get(name=experiment.name) 

self.assertEquals(len(experiment.tags), len(saved_experiment.tags.all())) # AssertError: 2 != 0
self.assertItemsEqual(experiment.tags, saved_experiment.tags.all())

Странно то, что в self.experiments теги установлены. Вызывается метод post_tags().

Модель:

class Experiment(models.Model):
     owner = models.ForeignKey(User, related_name='experiments') 

     name = models.CharField(max_length=32, default='')
     start_date = models.DateField()

     tags = TaggableManager()

person user3142459    schedule 11.11.2014    source источник


Ответы (2)


наконец нашел решение:

@factory.post_generation
def post_tags(self, create, extracted, **kwargs):
    self.tags.add(u'abc, cde', u'xzy')
person user3142459    schedule 11.11.2014
comment
Хотя этот фрагмент кода может решить вопрос, включение объяснения действительно помогает улучшить качество вашего поста. Помните, что вы отвечаете на вопрос для будущих читателей, и эти люди могут не знать причин вашего предложения кода. - person gunr2171; 11.11.2014

Для всех, кто приходит сюда и хочет получить более общий пример использования Factory Boy и django-taggit, документы Factory Boy включите полезный пример Many-to-Many. Так:

import factory

from myapp.models import Experiment


class ExperimentFactory(factory.DjangoModelFactory):
    class Meta:
        model = Experiment

    # other fields here

    @factory.post_generation
    def tags(self, create, extracted, **kwargs):
        if not create:
            # Simple build, do nothing.
            return

        if extracted:
            # A list of tags were passed in, use them.
            for tag in extracted:
                self.tags.add(tag)

Затем вы можете сделать:

from myapp.factories import ExperimentFactory

ExperimentFactory(name='A Name', tags=['Tag 1', 'Tag 2', 'Another tag',])

Обратите внимание, что это не создаст теги, если вы сделаете ExperimentFactory.build(), только если вы сделаете ExperimentFactory.create() или его синоним ExperimentFactory().

person Phil Gyford    schedule 06.04.2017