How to pass initial sequence number in Django factory_boy factory?

factory_boy is the default for 1 for sequences. How can I pass in a number to be used instead of another starting number? I can subclass the _setup_next_sequence() method, but how can I give it a variable to use?

 # 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() 

I am using factory_boy 1.2.0 (via pip install factory_boy )
factory_boy code: https://github.com/dnerdy/factory_boy

+4
source share
4 answers

I found two ways to resolve this issue:

  • Use the module variable
  • Use a class attribute outside the class definition

Use the module variable:

 # 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() 

Use a class attribute set outside the class definition:

 # 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 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() 
+1
source

In addition to Rob Bednark's answer

We can use the reset_sequence() function, which will reset the counter to a value .

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

Update: factory_boy now processing it!

In the latest version of factory_boy ( 2.8.1 to this day), you can now force the sequence counter to determine the value:

Forced value for each call

To force a counter for a specific Factory instance, just pass the value to __sequence=42 :

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

Then in the console:

 >>> 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 

And it is also possible to reset the counter for a specific value:

 >>> AccountFactory.reset_sequence(42) >>> AccountFactory().uid 42 >>> AccountFactory().uid 43 
+1
source

The third and easiest way:

 # 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 

I'm just starting out with Factory Boy myself, and I'm also not too experienced in Python, so maybe something is missing, but you can see where I'm going. To make it clearer, I think I would prefer it to be a keyword:

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

Source: https://habr.com/ru/post/1469148/


All Articles