summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphaël Barrois <raphael.barrois@polytechnique.org>2014-05-18 14:46:03 +0200
committerRaphaël Barrois <raphael.barrois@polytechnique.org>2014-05-18 14:46:03 +0200
commitb245a83019a8735d0c80c07275cd426bc60dd9f8 (patch)
tree00c936e2479056d829f3d6377a68f3e5cbb6af50
parentfd3d2583580fc18ff1531b5be02238c8c2addccc (diff)
downloadfactory-boy-b245a83019a8735d0c80c07275cd426bc60dd9f8.tar
factory-boy-b245a83019a8735d0c80c07275cd426bc60dd9f8.tar.gz
Update docs for class Meta.
-rw-r--r--README.rst21
-rw-r--r--docs/examples.rst6
-rw-r--r--docs/introduction.rst41
-rw-r--r--docs/orms.rst47
-rw-r--r--docs/recipes.rst40
-rw-r--r--docs/reference.rst219
6 files changed, 265 insertions, 109 deletions
diff --git a/README.rst b/README.rst
index b35adc5..787d754 100644
--- a/README.rst
+++ b/README.rst
@@ -94,7 +94,8 @@ Usage
Defining factories
""""""""""""""""""
-Factories declare a set of attributes used to instantiate an object. The class of the object must be defined in the FACTORY_FOR attribute:
+Factories declare a set of attributes used to instantiate an object.
+The class of the object must be defined in the ``target`` field of a ``class Meta:`` attribute:
.. code-block:: python
@@ -102,7 +103,8 @@ Factories declare a set of attributes used to instantiate an object. The class o
from . import models
class UserFactory(factory.Factory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
first_name = 'John'
last_name = 'Doe'
@@ -110,7 +112,8 @@ Factories declare a set of attributes used to instantiate an object. The class o
# Another, different, factory for the same object
class AdminFactory(factory.Factory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
first_name = 'Admin'
last_name = 'User'
@@ -164,7 +167,9 @@ These "lazy" attributes can be added as follows:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
+
first_name = 'Joe'
last_name = 'Blow'
email = factory.LazyAttribute(lambda a: '{0}.{1}@example.com'.format(a.first_name, a.last_name).lower())
@@ -183,7 +188,9 @@ Unique values in a specific format (for example, e-mail addresses) can be genera
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
+
email = factory.Sequence(lambda n: 'person{0}@example.com'.format(n))
>>> UserFactory().email
@@ -201,7 +208,9 @@ This is handled by the ``SubFactory`` helper:
.. code-block:: python
class PostFactory(factory.Factory):
- FACTORY_FOR = models.Post
+ class Meta:
+ target = models.Post
+
author = factory.SubFactory(UserFactory)
diff --git a/docs/examples.rst b/docs/examples.rst
index aab990a..52a5ef6 100644
--- a/docs/examples.rst
+++ b/docs/examples.rst
@@ -56,14 +56,16 @@ And now, we'll define the related factories:
class AccountFactory(factory.Factory):
- FACTORY_FOR = objects.Account
+ class Meta:
+ target = objects.Account
username = factory.Sequence(lambda n: 'john%s' % n)
email = factory.LazyAttribute(lambda o: '%s@example.org' % o.username)
class ProfileFactory(factory.Factory):
- FACTORY_FOR = objects.Profile
+ class Meta:
+ target = objects.Profile
account = factory.SubFactory(AccountFactory)
gender = factory.Iterator([objects.Profile.GENDER_MALE, objects.Profile.GENDER_FEMALE])
diff --git a/docs/introduction.rst b/docs/introduction.rst
index 86e2046..6ea6b5e 100644
--- a/docs/introduction.rst
+++ b/docs/introduction.rst
@@ -18,10 +18,11 @@ Basic usage
-----------
-Factories declare a set of attributes used to instantiate an object, whose class is defined in the FACTORY_FOR attribute:
+Factories declare a set of attributes used to instantiate an object, whose class is defined in the ``class Meta``'s ``target`` attribute:
- Subclass ``factory.Factory`` (or a more suitable subclass)
-- Set its ``FACTORY_FOR`` attribute to the target class
+- Add a ``class Meta:`` block
+- Set its ``target`` attribute to the target class
- Add defaults for keyword args to pass to the associated class' ``__init__`` method
@@ -31,7 +32,8 @@ Factories declare a set of attributes used to instantiate an object, whose class
from . import base
class UserFactory(factory.Factory):
- FACTORY_FOR = base.User
+ class Meta:
+ target = base.User
firstname = "John"
lastname = "Doe"
@@ -56,7 +58,8 @@ A given class may be associated to many :class:`~factory.Factory` subclasses:
.. code-block:: python
class EnglishUserFactory(factory.Factory):
- FACTORY_FOR = base.User
+ class Meta:
+ target = base.User
firstname = "John"
lastname = "Doe"
@@ -64,7 +67,8 @@ A given class may be associated to many :class:`~factory.Factory` subclasses:
class FrenchUserFactory(factory.Factory):
- FACTORY_FOR = base.User
+ class Meta:
+ target = base.User
firstname = "Jean"
lastname = "Dupont"
@@ -88,7 +92,8 @@ This is achieved with the :class:`~factory.Sequence` declaration:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
username = factory.Sequence(lambda n: 'user%d' % n)
@@ -104,7 +109,8 @@ This is achieved with the :class:`~factory.Sequence` declaration:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
@factory.sequence
def username(n):
@@ -121,7 +127,8 @@ taking the object being built and returning the value for the field:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
username = factory.Sequence(lambda n: 'user%d' % n)
email = factory.LazyAttribute(lambda obj: '%s@example.com' % obj.username)
@@ -146,7 +153,8 @@ taking the object being built and returning the value for the field:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
username = factory.Sequence(lambda n: 'user%d' % n)
@@ -168,7 +176,8 @@ and update them with its own declarations:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = base.User
+ class Meta:
+ target = base.User
firstname = "John"
lastname = "Doe"
@@ -209,13 +218,14 @@ Non-kwarg arguments
Some classes take a few, non-kwarg arguments first.
-This is handled by the :data:`~factory.Factory.FACTORY_ARG_PARAMETERS` attribute:
+This is handled by the :data:`~factory.FactoryOptions.arg_parameters` attribute:
.. code-block:: python
class MyFactory(factory.Factory):
- FACTORY_FOR = MyClass
- FACTORY_ARG_PARAMETERS = ('x', 'y')
+ class Meta:
+ target = MyClass
+ arg_parameters = ('x', 'y')
x = 1
y = 2
@@ -251,7 +261,8 @@ Calling a :class:`~factory.Factory` subclass will provide an object through the
.. code-block:: python
class MyFactory(factory.Factory):
- FACTORY_FOR = MyClass
+ class Meta:
+ target = MyClass
.. code-block:: pycon
@@ -265,6 +276,6 @@ Calling a :class:`~factory.Factory` subclass will provide an object through the
<MyClass: X (saved)>
-The default strategy can be changed by setting the class-level :attr:`~factory.Factory.FACTORY_STRATEGY` attribute.
+The default strategy can be changed by setting the ``class Meta`` :attr:`~factory.FactoryOptions.strategy` attribute.
diff --git a/docs/orms.rst b/docs/orms.rst
index c893cac..5ef8568 100644
--- a/docs/orms.rst
+++ b/docs/orms.rst
@@ -32,7 +32,7 @@ All factories for a Django :class:`~django.db.models.Model` should use the
This class provides the following features:
- * The :attr:`~factory.Factory.FACTORY_FOR` attribute also supports the ``'app.Model'``
+ * The :attr:`~factory.FactoryOption.target` attribute also supports the ``'app.Model'``
syntax
* :func:`~factory.Factory.create()` uses :meth:`Model.objects.create() <django.db.models.query.QuerySet.create>`
* :func:`~factory.Factory._setup_next_sequence()` selects the next unused primary key value
@@ -40,7 +40,12 @@ All factories for a Django :class:`~django.db.models.Model` should use the
attributes, the base object will be :meth:`saved <django.db.models.Model.save>`
once all post-generation hooks have run.
- .. attribute:: FACTORY_DJANGO_GET_OR_CREATE
+
+.. class:: DjangoOptions(factory.base.FactoryOptions)
+
+ The ``class Meta`` on a :class:`~DjangoModelFactory` supports an extra parameter:
+
+ .. attribute:: django_get_or_create
Fields whose name are passed in this list will be used to perform a
:meth:`Model.objects.get_or_create() <django.db.models.query.QuerySet.get_or_create>`
@@ -49,8 +54,9 @@ All factories for a Django :class:`~django.db.models.Model` should use the
.. code-block:: python
class UserFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = 'myapp.User' # Equivalent to ``FACTORY_FOR = myapp.models.User``
- FACTORY_DJANGO_GET_OR_CREATE = ('username',)
+ class Meta:
+ target = 'myapp.User' # Equivalent to ``target = myapp.models.User``
+ django_get_or_create = ('username',)
username = 'john'
@@ -80,11 +86,13 @@ All factories for a Django :class:`~django.db.models.Model` should use the
.. code-block:: python
class MyAbstractModelFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.MyAbstractModel
- ABSTRACT_FACTORY = True
+ class Meta:
+ target = models.MyAbstractModel
+ abstract = True
class MyConcreteModelFactory(MyAbstractModelFactory):
- FACTORY_FOR = models.MyConcreteModel
+ class Meta:
+ target = models.MyConcreteModel
Otherwise, factory_boy will try to get the 'next PK' counter from the abstract model.
@@ -112,7 +120,8 @@ Extra fields
.. code-block:: python
class MyFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.MyModel
+ class Meta:
+ target = models.MyModel
the_file = factory.django.FileField(filename='the_file.dat')
@@ -149,7 +158,8 @@ Extra fields
.. code-block:: python
class MyFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.MyModel
+ class Meta:
+ target = models.MyModel
the_image = factory.django.ImageField(color='blue')
@@ -188,7 +198,8 @@ To work around this problem, use the :meth:`mute_signals()` decorator/context ma
@factory.django.mute_signals(signals.pre_save, signals.post_save)
class FooFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.Foo
+ class Meta:
+ target = models.Foo
# ...
@@ -241,7 +252,7 @@ factory_boy supports `MongoEngine`_-style models, through the :class:`MongoEngin
* :func:`~factory.Factory.create()` builds an instance through ``__init__`` then
saves it.
- .. note:: If the :attr:`associated class <factory.Factory.FACTORY_FOR>` is a :class:`mongoengine.EmbeddedDocument`,
+ .. note:: If the :attr:`associated class <factory.FactoryOptions.target>` is a :class:`mongoengine.EmbeddedDocument`,
the :meth:`~MongoEngineFactory.create` function won't "save" it, since this wouldn't make sense.
This feature makes it possible to use :class:`~factory.SubFactory` to create embedded document.
@@ -255,7 +266,7 @@ SQLAlchemy
Factoy_boy also supports `SQLAlchemy`_ models through the :class:`SQLAlchemyModelFactory` class.
-To work, this class needs an `SQLAlchemy`_ session object affected to "FACTORY_SESSION" class attribute.
+To work, this class needs an `SQLAlchemy`_ session object affected to the ``Meta.sqlalchemy_session`` attribute.
.. _SQLAlchemy: http://www.sqlalchemy.org/
@@ -268,7 +279,12 @@ To work, this class needs an `SQLAlchemy`_ session object affected to "FACTORY_S
* :func:`~factory.Factory.create()` uses :meth:`sqlalchemy.orm.session.Session.add`
* :func:`~factory.Factory._setup_next_sequence()` selects the next unused primary key value
- .. attribute:: FACTORY_SESSION
+.. class:: SQLAlchemyOptions(factory.base.FactoryOptions)
+
+ In addition to the usual parameters available in :class:`class Meta <factory.base.FactoryOptions>`,
+ a :class:`SQLAlchemyModelFactory` also supports the following settings:
+
+ .. attribute:: sqlalchemy_session
Fields whose SQLAlchemy session object are passed will be used to communicate with the database
@@ -297,8 +313,9 @@ A (very) simple exemple:
class UserFactory(SQLAlchemyModelFactory):
- FACTORY_FOR = User
- FACTORY_SESSION = session # the SQLAlchemy session object
+ class Meta:
+ target = User
+ sqlalchemy_session = session # the SQLAlchemy session object
id = factory.Sequence(lambda n: n)
name = factory.Sequence(lambda n: u'User %d' % n)
diff --git a/docs/recipes.rst b/docs/recipes.rst
index 7a6bf23..917bc3c 100644
--- a/docs/recipes.rst
+++ b/docs/recipes.rst
@@ -26,7 +26,8 @@ use the :class:`~factory.SubFactory` declaration:
from . import models
class UserFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
first_name = factory.Sequence(lambda n: "Agent %03d" % n)
group = factory.SubFactory(GroupFactory)
@@ -53,7 +54,8 @@ use a :class:`~factory.RelatedFactory` declaration:
# factories.py
class UserFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
log = factory.RelatedFactory(UserLogFactory, 'user', action=models.UserLog.ACTION_CREATE)
@@ -75,7 +77,8 @@ factory_boy allows to define attributes of such profiles dynamically when creati
.. code-block:: python
class ProfileFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = my_models.Profile
+ class Meta:
+ target = my_models.Profile
title = 'Dr'
# We pass in profile=None to prevent UserFactory from creating another profile
@@ -83,7 +86,8 @@ factory_boy allows to define attributes of such profiles dynamically when creati
user = factory.SubFactory('app.factories.UserFactory', profile=None)
class UserFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = auth_models.User
+ class Meta:
+ target = auth_models.User
username = factory.Sequence(lambda n: "user_%d" % n)
@@ -145,12 +149,14 @@ hook:
# factories.py
class GroupFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.Group
+ class Meta:
+ target = models.Group
name = factory.Sequence(lambda n: "Group #%s" % n)
class UserFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
name = "John Doe"
@@ -200,17 +206,20 @@ If more links are needed, simply add more :class:`RelatedFactory` declarations:
# factories.py
class UserFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
name = "John Doe"
class GroupFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.Group
+ class Meta:
+ target = models.Group
name = "Admins"
class GroupLevelFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.GroupLevel
+ class Meta:
+ target = models.GroupLevel
user = factory.SubFactory(UserFactory)
group = factory.SubFactory(GroupFactory)
@@ -273,20 +282,23 @@ Here, we want:
# factories.py
class CountryFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.Country
+ class Meta:
+ target = models.Country
name = factory.Iterator(["France", "Italy", "Spain"])
lang = factory.Iterator(['fr', 'it', 'es'])
class UserFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
name = "John"
lang = factory.SelfAttribute('country.lang')
country = factory.SubFactory(CountryFactory)
class CompanyFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.Company
+ class Meta:
+ target = models.Company
name = "ACME, Inc."
country = factory.SubFactory(CountryFactory)
@@ -302,7 +314,9 @@ default :meth:`Model.objects.create() <django.db.models.query.QuerySet.create>`
.. code-block:: python
class UserFactory(factory.DjangoModelFactory):
- FACTORY_FOR = UserenaSignup
+ class Meta:
+ target = UserenaSignup
+
username = "l7d8s"
email = "my_name@example.com"
password = "my_password"
diff --git a/docs/reference.rst b/docs/reference.rst
index 53584a0..f19b44e 100644
--- a/docs/reference.rst
+++ b/docs/reference.rst
@@ -11,37 +11,54 @@ For internals and customization points, please refer to the :doc:`internals` sec
The :class:`Factory` class
--------------------------
-.. class:: Factory
+.. class:: FactoryOptions
+
+ .. versionadded:: 2.4.0
+
+ A :class:`Factory`'s behaviour can be tuned through a few settings.
+
+ For convenience, they are declared in a single ``class Meta`` attribute:
- The :class:`Factory` class is the base of factory_boy features.
+ .. code-block:: python
- It accepts a few specific attributes (must be specified on class declaration):
+ class MyFactory(factory.Factory):
+ class Meta:
+ target = MyObject
+ abstract = False
- .. attribute:: FACTORY_FOR
+ .. attribute:: target
This optional attribute describes the class of objects to generate.
If unset, it will be inherited from parent :class:`Factory` subclasses.
- .. attribute:: ABSTRACT_FACTORY
+ .. versionadded:: 2.4.0
+
+ .. attribute:: abstract
This attribute indicates that the :class:`Factory` subclass should not
be used to generate objects, but instead provides some extra defaults.
It will be automatically set to ``True`` if neither the :class:`Factory`
- subclass nor its parents define the :attr:`~Factory.FACTORY_FOR` attribute.
+ subclass nor its parents define the :attr:`~FactoryOptions.target` attribute.
+
+ .. warning:: This flag is reset to ``False`` When a :class:`Factory` subclasses
+ another one if a :attr:`~FactoryOptions.target` is set.
+
+ .. versionadded:: 2.4.0
- .. attribute:: FACTORY_ARG_PARAMETERS
+ .. attribute:: arg_parameters
Some factories require non-keyword arguments to their :meth:`~object.__init__`.
- They should be listed, in order, in the :attr:`FACTORY_ARG_PARAMETERS`
+ They should be listed, in order, in the :attr:`arg_parameters`
attribute:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
- FACTORY_ARG_PARAMETERS = ('login', 'email')
+ class Meta:
+ target = User
+ arg_parameters = ('login', 'email')
login = 'john'
email = factory.LazyAttribute(lambda o: '%s@example.com' % o.login)
@@ -53,22 +70,25 @@ The :class:`Factory` class
<User: john>
>>> User('john', 'john@example.com', firstname="John") # actual call
- .. attribute:: FACTORY_HIDDEN_ARGS
+ .. versionadded:: 2.4.0
+
+ .. attribute:: hidden_args
While writing a :class:`Factory` for some object, it may be useful to
have general fields helping defining others, but that should not be
passed to the target class; for instance, a field named 'now' that would
hold a reference time used by other objects.
- Factory fields whose name are listed in :attr:`FACTORY_HIDDEN_ARGS` will
+ Factory fields whose name are listed in :attr:`hidden_args` will
be removed from the set of args/kwargs passed to the underlying class;
they can be any valid factory_boy declaration:
.. code-block:: python
class OrderFactory(factory.Factory):
- FACTORY_FOR = Order
- FACTORY_HIDDEN_ARGS = ('now',)
+ class Meta:
+ target = Order
+ hidden_args = ('now',)
now = factory.LazyAttribute(lambda o: datetime.datetime.utcnow())
started_at = factory.LazyAttribute(lambda o: o.now - datetime.timedelta(hours=1))
@@ -83,6 +103,55 @@ The :class:`Factory` class
>>> OrderFactory(now=datetime.datetime(2013, 4, 1, 10))
<Order: started 2013-04-01 09:00:00, paid 2013-04-01 09:10:00>
+ .. versionadded:: 2.4.0
+
+
+.. class:: Factory
+
+ .. note:: In previous versions, the fields of :class:`class Meta <factory.FactoryOptions>` were
+ defined as class attributes on :class:`Factory`. This is now deprecated and will be removed
+ in 2.5.0.
+
+ .. attribute:: FACTORY_FOR
+
+ .. deprecated:: 2.4.0
+ See :attr:`FactoryOptions.target`.
+
+ .. attribute:: ABSTRACT_FACTORY
+
+ .. deprecated:: 2.4.0
+ See :attr:`FactoryOptions.abstract`.
+
+ .. attribute:: FACTORY_ARG_PARAMETERS
+
+ .. deprecated:: 2.4.0
+ See :attr:`FactoryOptions.arg_parameters`.
+
+ .. attribute:: FACTORY_HIDDEN_ARGS
+
+ .. deprecated:: 2.4.0
+ See :attr:`FactoryOptions.hidden_args`.
+
+
+ **Class-level attributes:**
+
+ .. attribute:: _meta
+
+ .. versionadded:: 2.4.0
+
+ The :class:`FactoryOptions` instance attached to a :class:`Factory` class is available
+ as a :attr:`_meta` attribute.
+
+ .. attribute:: _options_class
+
+ .. versionadded:: 2.4.0
+
+ If a :class:`Factory` subclass needs to define additional, extra options, it has to
+ provide a custom :class:`FactoryOptions` subclass.
+
+ A pointer to that custom class should be provided as :attr:`_options_class` so that
+ the :class:`Factory`-building metaclass can use it instead.
+
**Base functions:**
@@ -162,7 +231,7 @@ The :class:`Factory` class
The :meth:`_adjust_kwargs` extension point allows for late fields tuning.
It is called once keyword arguments have been resolved and post-generation
- items removed, but before the :attr:`FACTORY_ARG_PARAMETERS` extraction
+ items removed, but before the :attr:`~FactoryOptions.arg_parameters` extraction
phase.
.. code-block:: python
@@ -194,7 +263,7 @@ The :class:`Factory` class
.. OHAI_VIM*
This class method is called whenever a new instance needs to be built.
- It receives the target class (provided to :attr:`FACTORY_FOR`), and
+ It receives the target class (provided to :attr:`~FactoryOptions.target`), and
the positional and keyword arguments to use for the class once all has
been computed.
@@ -214,7 +283,8 @@ The :class:`Factory` class
.. code-block:: python
class BaseBackendFactory(factory.Factory):
- ABSTRACT_FACTORY = True # Optional
+ class Meta:
+ abstract = True # Optional
def _create(cls, target_class, *args, **kwargs):
obj = target_class(*args, **kwargs)
@@ -254,7 +324,7 @@ The :class:`Factory` class
>>> SomeFactory._next_sequence
4
- Since subclasses of a non-:attr:`abstract <factory.Factory.ABSTRACT_FACTORY>`
+ Since subclasses of a non-:attr:`abstract <factory.FactoryOptions.abstract>`
:class:`~factory.Factory` share the same sequence counter, special care needs
to be taken when resetting the counter of such a subclass.
@@ -293,7 +363,7 @@ factory_boy supports two main strategies for generating instances, plus stubs.
but not persisted to any datastore.
It is usually a simple call to the :meth:`~object.__init__` method of the
- :attr:`~Factory.FACTORY_FOR` class.
+ :attr:`~FactoryOptions.target` class.
.. data:: CREATE_STRATEGY
@@ -316,7 +386,7 @@ factory_boy supports two main strategies for generating instances, plus stubs.
when using the ``create`` strategy.
That policy will be used if the
- :attr:`associated class <Factory.FACTORY_FOR>` has an ``objects``
+ :attr:`associated class <FactoryOptions.target>` has an ``objects``
attribute *and* the :meth:`~Factory._create` classmethod of the
:class:`Factory` wasn't overridden.
@@ -337,7 +407,7 @@ factory_boy supports two main strategies for generating instances, plus stubs.
.. data:: STUB_STRATEGY
The 'stub' strategy is an exception in the factory_boy world: it doesn't return
- an instance of the :attr:`~Factory.FACTORY_FOR` class, and actually doesn't
+ an instance of the :attr:`~FactoryOptions.target` class, and actually doesn't
require one to be present.
Instead, it returns an instance of :class:`StubObject` whose attributes have been
@@ -359,7 +429,7 @@ factory_boy supports two main strategies for generating instances, plus stubs.
.. class:: StubFactory(Factory)
- An :attr:`abstract <Factory.ABSTRACT_FACTORY>` :class:`Factory`,
+ An :attr:`abstract <FactoryOptions.abstract>` :class:`Factory`,
with a default strategy set to :data:`STUB_STRATEGY`.
@@ -414,7 +484,8 @@ accept the object being built as sole argument, and return a value.
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
username = 'john'
email = factory.LazyAttribute(lambda o: '%s@example.com' % o.username)
@@ -449,7 +520,8 @@ return value of the method:
.. code-block:: python
class UserFactory(factory.Factory)
- FACTORY_FOR = User
+ class Meta:
+ target = User
name = u"Jean"
@@ -487,7 +559,8 @@ This declaration takes a single argument, a function accepting a single paramete
.. code-block:: python
class UserFactory(factory.Factory)
- FACTORY_FOR = User
+ class Meta:
+ target = User
phone = factory.Sequence(lambda n: '123-555-%04d' % n)
@@ -512,7 +585,8 @@ be the sequence counter - this might be confusing:
.. code-block:: python
class UserFactory(factory.Factory)
- FACTORY_FOR = User
+ class Meta:
+ target = User
@factory.sequence
def phone(n):
@@ -537,7 +611,8 @@ The sequence counter is shared across all :class:`Sequence` attributes of the
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
phone = factory.Sequence(lambda n: '%04d' % n)
office = factory.Sequence(lambda n: 'A23-B%03d' % n)
@@ -561,7 +636,8 @@ sequence counter is shared:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
phone = factory.Sequence(lambda n: '123-555-%04d' % n)
@@ -596,7 +672,8 @@ class-level value.
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
uid = factory.Sequence(int)
@@ -631,7 +708,8 @@ It takes a single argument, a function whose two parameters are, in order:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
login = 'john'
email = factory.LazyAttributeSequence(lambda o, n: '%s@s%d.example.com' % (o.login, n))
@@ -655,7 +733,8 @@ handles more complex cases:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
login = 'john'
@@ -692,7 +771,8 @@ The :class:`SubFactory` attribute should be called with:
.. code-block:: python
class FooFactory(factory.Factory):
- FACTORY_FOR = Foo
+ class Meta:
+ target = Foo
bar = factory.SubFactory(BarFactory) # Not BarFactory()
@@ -705,7 +785,8 @@ Definition
# A standard factory
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
# Various fields
first_name = 'John'
@@ -714,7 +795,8 @@ Definition
# A factory for an object with a 'User' field
class CompanyFactory(factory.Factory):
- FACTORY_FOR = Company
+ class Meta:
+ target = Company
name = factory.Sequence(lambda n: 'FactoryBoyz' + 'z' * n)
@@ -794,13 +876,15 @@ This issue can be handled by passing the absolute import path to the target
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
username = 'john'
main_group = factory.SubFactory('users.factories.GroupFactory')
class GroupFactory(factory.Factory):
- FACTORY_FOR = Group
+ class Meta:
+ target = Group
name = "MyGroup"
owner = factory.SubFactory(UserFactory)
@@ -828,7 +912,8 @@ That declaration takes a single argument, a dot-delimited path to the attribute
.. code-block:: python
class UserFactory(factory.Factory)
- FACTORY_FOR = User
+ class Meta:
+ target = User
birthdate = factory.Sequence(lambda n: datetime.date(2000, 1, 1) + datetime.timedelta(days=n))
birthmonth = factory.SelfAttribute('birthdate.month')
@@ -854,13 +939,15 @@ gains an "upward" semantic through the double-dot notation, as used in Python im
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
language = 'en'
class CompanyFactory(factory.Factory):
- FACTORY_FOR = Company
+ class Meta:
+ target = Company
country = factory.SubFactory(CountryFactory)
owner = factory.SubFactory(UserFactory, language=factory.SelfAttribute('..country.language'))
@@ -888,7 +975,8 @@ through the :attr:`~containers.LazyStub.factory_parent` attribute of the passed-
.. code-block:: python
class CompanyFactory(factory.Factory):
- FACTORY_FOR = Company
+ class Meta:
+ target = Company
country = factory.SubFactory(CountryFactory)
owner = factory.SubFactory(UserFactory,
language=factory.LazyAttribute(lambda user: user.factory_parent.country.language),
@@ -966,7 +1054,8 @@ adequate value.
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
# CATEGORY_CHOICES is a list of (key, title) tuples
category = factory.Iterator(User.CATEGORY_CHOICES, getter=lambda c: c[0])
@@ -987,7 +1076,8 @@ use the :func:`iterator` decorator:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
@factory.iterator
def name():
@@ -1030,7 +1120,8 @@ with the :class:`Dict` and :class:`List` attributes:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
is_superuser = False
roles = factory.Dict({
@@ -1066,7 +1157,8 @@ with the :class:`Dict` and :class:`List` attributes:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
flags = factory.List([
'user',
@@ -1113,7 +1205,8 @@ For instance, a :class:`PostGeneration` hook is declared as ``post``:
.. code-block:: python
class SomeFactory(factory.Factory):
- FACTORY_FOR = SomeObject
+ class Meta:
+ target = SomeObject
@post_generation
def post(self, create, extracted, **kwargs):
@@ -1128,7 +1221,7 @@ When calling the factory, some arguments will be extracted for this method:
- Any argument starting with ``post__XYZ`` will be extracted, its ``post__`` prefix
removed, and added to the kwargs passed to the post-generation hook.
-Extracted arguments won't be passed to the :attr:`~Factory.FACTORY_FOR` class.
+Extracted arguments won't be passed to the :attr:`~FactoryOptions.target` class.
Thus, in the following call:
@@ -1142,7 +1235,7 @@ Thus, in the following call:
)
The ``post`` hook will receive ``1`` as ``extracted`` and ``{'y': 3, 'z__t': 42}``
-as keyword arguments; ``{'post_x': 2}`` will be passed to ``SomeFactory.FACTORY_FOR``.
+as keyword arguments; ``{'post_x': 2}`` will be passed to ``SomeFactory._meta.target``.
RelatedFactory
@@ -1184,7 +1277,8 @@ RelatedFactory
.. code-block:: python
class FooFactory(factory.Factory):
- FACTORY_FOR = Foo
+ class Meta:
+ target = Foo
bar = factory.RelatedFactory(BarFactory) # Not BarFactory()
@@ -1192,13 +1286,15 @@ RelatedFactory
.. code-block:: python
class CityFactory(factory.Factory):
- FACTORY_FOR = City
+ class Meta:
+ target = City
capital_of = None
name = "Toronto"
class CountryFactory(factory.Factory):
- FACTORY_FOR = Country
+ class Meta:
+ target = Country
lang = 'fr'
capital_city = factory.RelatedFactory(CityFactory, 'capital_of', name="Paris")
@@ -1260,7 +1356,8 @@ as ``callable(obj, create, extracted, **kwargs)``, where:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
login = 'john'
make_mbox = factory.PostGeneration(
@@ -1280,7 +1377,8 @@ A decorator is also provided, decorating a single method accepting the same
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
login = 'john'
@@ -1316,7 +1414,7 @@ PostGenerationMethodCall
.. attribute:: method_name
- The name of the method to call on the :attr:`~Factory.FACTORY_FOR` object
+ The name of the method to call on the :attr:`~FactoryOptions.target` object
.. attribute:: args
@@ -1340,7 +1438,8 @@ attribute like below:
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
username = 'user'
password = factory.PostGenerationMethodCall('set_password',
@@ -1390,7 +1489,8 @@ factory during instantiation.
.. code-block:: python
class UserFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
username = 'user'
password = factory.PostGenerationMethodCall('set_password',
@@ -1404,7 +1504,8 @@ example, if we declared the ``password`` attribute like the following,
.. code-block:: python
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
username = 'user'
password = factory.PostGenerationMethodCall('set_password', '', 'sha1')
@@ -1467,7 +1568,8 @@ Lightweight factory declaration
# This is equivalent to:
class UserFactory(factory.Factory):
- FACTORY_FOR = User
+ class Meta:
+ target = User
login = 'john'
email = factory.LazyAttribute(lambda u: '%s@example.com' % u.login)
@@ -1486,7 +1588,8 @@ Lightweight factory declaration
# This is equivalent to:
class UserFactory(factory.django.DjangoModelFactory):
- FACTORY_FOR = models.User
+ class Meta:
+ target = models.User
login = 'john'
email = factory.LazyAttribute(lambda u: '%s@example.com' % u.login)