Reputation: 640
How can I create a field in Factory-Boy to TaggableManager from django-taggit?
The following does not work:
First:
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']
The error is: TypeError: 'tags' is an invalid keyword argument for this function
Second: (with factory.post_generation
). So Instead of the last line there is
@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
I get as result by Experiment.objects.get(pk=1).tags
is []
For some details:
The testing of the objects in a TestCase
is:
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())
The odd thing is that in self.experiments
the tags are set. The post_tags()
method is called.
The model is:
class Experiment(models.Model):
owner = models.ForeignKey(User, related_name='experiments')
name = models.CharField(max_length=32, default='')
start_date = models.DateField()
tags = TaggableManager()
Upvotes: 3
Views: 2059
Reputation: 14624
For anyone else coming here who wants a more generalised example of using Factory Boy and django-taggit, the Factory Boy docs include a Many-to-Many example which is useful. So:
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)
Then you can do:
from myapp.factories import ExperimentFactory
ExperimentFactory(name='A Name', tags=['Tag 1', 'Tag 2', 'Another tag',])
Note, this won't create tags if you do ExperimentFactory.build()
, only if you do ExperimentFactory.create()
or its synonym ExperimentFactory()
.
Upvotes: 5
Reputation: 640
finally found the solution:
@factory.post_generation
def post_tags(self, create, extracted, **kwargs):
self.tags.add(u'abc, cde', u'xzy')
Upvotes: 2