【问题标题】:How to pass in a starting sequence number to a Django factory_boy factory?如何将起始序列号传递给 Django factory_boy 工厂?
【发布时间】:2013-03-14 05:59:49
【问题描述】:

factory_boy 默认为1 用于序列。如何传递一个数字以用作不同的起始数字?我可以继承_setup_next_sequence() 方法,但我怎样才能给它一个变量来使用呢?

# File: models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)


# File: factories.py
from .models import Book
import factory

class BookFactory(factory.Factory):
  FACTORY_FOR = BookModel  
  title = factory.Sequence(lambda n: u'Title #{}'.format(n))

  @classmethod
  def _setup_next_sequence(cls):      
      # Instead of defaulting to starting with number 1, start with starting_seq_num.
      # But how do I set starting_seq_num?
      return starting_seq_num


# File: make_data.py
from factories import BookFactory

# somehow set starting sequence number here?

BookFactory().create()

我正在使用 factory_boy 1.2.0(来自 pip install factory_boy
factory_boy 代码:https://github.com/dnerdy/factory_boy

【问题讨论】:

    标签: python django class-method factory-boy


    【解决方案1】:

    除了Rob Bednark的回答

    我们可以使用reset_sequence() 函数,它会将计数器重置特定值

    # File: make_data.py
    import factories
    
    factories.BookFactory.reset_sequence(100)
    my_book = factories.BookFactory().create()
    print(my_book.title) # Title #100
    

    【讨论】:

      【解决方案2】:

      更新:factory_boy 现在处理它!

      在最新版本的factory_boy2.8.1 至今)中,现在可以将force the sequence counter 定义为一个值:

      在每次调用的基础上强制该值

      为了对特定的Factory 实例化强制计数器,只需将值传递给 __sequence=42参数:

      class AccountFactory(factory.Factory):
              class Meta:
                  model = Account
              uid = factory.Sequence(lambda n: n)
              name = "Test"
      

      然后在控制台中:

      >>> obj1 = AccountFactory(name="John Doe", __sequence=10)
      >>> obj1.uid  # Taken from the __sequence counter
      10
      >>> obj2 = AccountFactory(name="Jane Doe")
      >>> obj2.uid  # The base sequence counter hasn't changed
      1
      

      并且还可以将计数器重置为特定值:

      >>> AccountFactory.reset_sequence(42)
      >>> AccountFactory().uid
      42
      >>> AccountFactory().uid
      43
      

      【讨论】:

        【解决方案3】:

        我找到了两种解决方法:

        1. 使用模块变量
        2. 使用类定义之外的类属性集

        使用模块变量:

        # File: factories.py
        from .models import Book
        import factory
        
        starting_seq_num = 0
        
        class BookFactory(factory.Factory):
          FACTORY_FOR = BookModel  
          title = factory.Sequence(lambda n: u'Title #{}'.format(n))
        
          @classmethod
          def _setup_next_sequence(cls):      
              # Instead of defaulting to starting with 0, start with starting_seq_num.
              return starting_seq_num
        
        # File: make_data.py
        import factories
        
        factories.starting_seq_num = 100    
        factories.BookFactory().create()
        

        使用类定义之外的类属性集:

        # File: factories.py
        from .models import Book
        import factory
        
        class BookFactory(factory.Factory):
          # Note that starting_seq_num cannot be set here in the class definition,
          # because Factory will then pass it as a kwarg to the model's create() method
          # and cause an exception.  It must be set outside the class definition.
          FACTORY_FOR = BookModel  
          title = factory.Sequence(lambda n: u'Title #{}'.format(n))
        
          @classmethod
          def _setup_next_sequence(cls):      
              return getattr(cls, 'starting_seq_num', 0)
        
        # File: make_data.py
        from factories import BookFactory
        
        BookFactory.starting_seq_num = 100
        BookFactory().create()
        

        【讨论】:

          【解决方案4】:

          第三种也是最简单的方法:

          # File: factories.py
          from .models import BookModel
          import factory
          
          class BookFactory(factory.Factory, starting_seq_num):
            FACTORY_FOR = BookModel  
            title = factory.Sequence(lambda n: u'Title #{}'.format(n + starting_seq_num))
          
          # File: make_data.py
          import factories
          
          book = factories.BookFactory(512).create()  #Start with 512
          

          我自己只是从 Factory Boy 开始,在 Python 方面也没有太多经验,所以我可能会遗漏一些东西,但你知道我要去哪里。为了更清楚,我想我实际上更喜欢它被关键字:

          class BookFactory(factory.Factory, title_seq_start=-1):
          ...
          book = factories.BookFactory(title_seq_start=512).create()
          

          【讨论】:

          • 这会引发错误。你是如何从未定义的变量扩展而来的?
          猜你喜欢
          • 1970-01-01
          • 2015-11-29
          • 1970-01-01
          • 2011-01-18
          • 2012-08-29
          • 1970-01-01
          • 1970-01-01
          • 2019-04-01
          • 2023-03-06
          相关资源
          最近更新 更多