2012-04-23 14 views
10

Actualmente estoy usando factory_boy para crear accesorios en mis pruebas. Factory_boy documentos mencionados solo acerca de SubFactory que podría actuar como un campo ForeignKey en un modelo. Sin embargo, no había nada en la asociación ManyToMany. Si tuviera un siguiente modelo de publicación, ¿cómo podría crear una fábrica para él?Python factory_boy library m2m en el modelo Django?

class Post(models.Model): 
    title = models.CharField(max_length=100) 
    tags = models.ManyToManyField('tags.Tag') 

class PostFactory(factory.Factory): 
    FACTORY_FOR = Post 

    title = 'My title' 
    tags = ??? 
+0

Hey @Ngo ¿obtuviste una respuesta que funcionó? – Daryl

+0

@Daryl: overriding _prepare parece ser la solución más fácil :) –

Respuesta

2

No he probado, pero ¿cuál es el problema:

class PostFactory(factory.Factory): 
    FACTORY_FOR = Post 
    title = 'My title' 

class TagFactory(factory.Factory): 
    FACTORY_FOR = Tag 

post = PostFactory() 
tag = TagFactory() 
post.tags.add(tag) 
+1

Sí, eso funciona. Pero me gustaría hacer esto: post = PostFactory() y vamos a decir 4 etiquetas agregadas automáticamente sin tener que especificar manualmente post.tags.add (tag) –

+0

No creo que factory_boy lo permita. Pero ¿por qué no creas una función que hace eso por ti? def PostFactoryWithFourTags(): post = PostFactory() para _ en xrange (4): post.tags.add (TagFactory() return post – Ale

7

Puede anular la _prepare classmethod:

class PostFactory(Factory): 
    FACTORY_FOR = Post 

    title = 'My title' 

    @classmethod 
    def _prepare(cls, create, **kwargs): 
     post = super(PostFactory, cls)._prepare(create, **kwargs) 
     if post.id: 
      post.tags = Tag.objects.all() 
     return post 

Tenga en cuenta que no se puede agregar etiquetas a una publicación si la publicación no tiene una ID.

11

¿Qué pasa con post_generation hook - Supongo que utiliza la versión más reciente de factory_boy?

import random 
import factory 

class PostFactory(factory.Factory): 
    FACTORY_FOR = Post 
    title = factory.Sequence(lambda n: "This is test title number" + n) 
    @factory.post_generation(extract_prefix='tags') 
    def add_tags(self, create, extracted, **kwargs): 
     # allow something like PostFactory(tags = Tag.objects.filter()) 
     if extracted and type(extracted) == type(Tag.objects.all()): 
      self.tags = extracted 
      self.save() 
     else: 
      if Tag.objects.all().count() < 5: 
       TagFactory.create_batch(5, **kwargs) 
      for tag in Tag.objects.all().order_by('?')[:random.randint(1, 5)]: 
       self.tags.add(tag) 

en cuenta que puede utilizar PostFactory(tags__field = 'some fancy default text'), pero recomiendo para crear buena TagFactory con secuencias ...

Usted debe ser capaz de unirse PostFactory(tags = Tag.objects.filter()) pero esta parte no se ha probado ...

Cuestiones relacionadas