2012-04-23 71 views
10

我目前使用factory_boy在我的測試中創建燈具。 Factory_boy docs只提及約SubFactory這可能像一個模型中的ForeignKey字段。但是,ManyToMany協會沒有任何內容。如果我有一個以下的Post模型,我將如何去爲它創建一個工廠?Django模型中的Python factory_boy庫m2m?

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

嘿@Ngo你有沒有得到一個有效的答案? – Daryl 2012-09-10 12:02:14

+0

@Daryl:覆蓋_prepare似乎是最簡單的解決方案:) – 2012-09-13 10:24:16

回答

2

我沒有測試它,但什麼是這個問題:

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

是的,那是有效的。但我想這樣做:post = PostFactory(),並且會有4個標籤自動添加,而無需手動指定post.tags.add(tag) – 2012-05-19 11:32:34

+0

我不認爲factory_boy允許這樣做。但爲什麼你不創建一個功能,爲你做到這一點? (): def PostFactoryWithFourTags(): post = PostFactory() for _ in xrange(4): post.tags.add(TagFactory() return post – Ale 2012-05-21 17:28:01

7

您可以覆蓋_prepare類方法:

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 

請注意,您不能添加標籤如果帖子沒有ID,則發帖。

11

post_generation hook - 我假設您使用較新版本的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) 

請注意,您可以使用PostFactory(tags__field = 'some fancy default text'),但我建議創造良好的TagFactory使用序列...

你應該能夠綁定PostFactory(tags = Tag.objects.filter())但這部分沒有測試......