Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass in a starting sequence number to a Django factory_boy factory?

factory_boy defaults to 1 for sequences. How can I pass in a number to use as a different starting number instead? 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'm using factory_boy 1.2.0 (via pip install factory_boy)
factory_boy code: https://github.com/dnerdy/factory_boy

like image 894
Rob Bednark Avatar asked Mar 14 '13 05:03

Rob Bednark


2 Answers

In addition to the answer of Rob Bednark

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

# File: make_data.py
import factories

factories.BookFactory.reset_sequence(100)
my_book = factories.BookFactory().create()
print(my_book.title) # Title #100
like image 66
MMayla Avatar answered Sep 28 '22 13:09

MMayla


I found two ways of solving this:

  1. Use a module variable
  2. Use a class attribute set outside of the class definition

Use a 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 of 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'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()
like image 28
Rob Bednark Avatar answered Sep 28 '22 11:09

Rob Bednark