1Reference 2========= 3 4.. currentmodule:: factory 5 6This section offers an in-depth description of factory_boy features. 7 8For internals and customization points, please refer to the :doc:`internals` section. 9 10 11The :class:`Factory` class 12-------------------------- 13 14Meta options 15"""""""""""" 16 17.. class:: FactoryOptions 18 19 .. versionadded:: 2.4.0 20 21 A :class:`Factory`'s behavior can be tuned through a few settings. 22 23 For convenience, they are declared in a single ``class Meta`` attribute: 24 25 .. code-block:: python 26 27 class MyFactory(factory.Factory): 28 class Meta: 29 model = MyObject 30 abstract = False 31 32 .. attribute:: model 33 34 This optional attribute describes the class of objects to generate. 35 36 If unset, it will be inherited from parent :class:`Factory` subclasses. 37 38 .. versionadded:: 2.4.0 39 40 .. method:: get_model_class() 41 42 Returns the actual model class (:attr:`FactoryOptions.model` might be the 43 path to the class; this function will always return a proper class). 44 45 .. attribute:: abstract 46 47 This attribute indicates that the :class:`Factory` subclass should not 48 be used to generate objects, but instead provides some extra defaults. 49 50 It will be automatically set to ``True`` if neither the :class:`Factory` 51 subclass nor its parents define the :attr:`~FactoryOptions.model` attribute. 52 53 .. warning:: This flag is reset to ``False`` when a :class:`Factory` subclasses 54 another one if a :attr:`~FactoryOptions.model` is set. 55 56 .. versionadded:: 2.4.0 57 58 .. attribute:: inline_args 59 60 Some factories require non-keyword arguments to their :meth:`~object.__init__`. 61 They should be listed, in order, in the :attr:`inline_args` 62 attribute: 63 64 .. code-block:: python 65 66 class UserFactory(factory.Factory): 67 class Meta: 68 model = User 69 inline_args = ('login', 'email') 70 71 login = 'john' 72 email = factory.LazyAttribute(lambda o: '%s@example.com' % o.login) 73 firstname = "John" 74 75 .. code-block:: pycon 76 77 >>> UserFactory() 78 <User: john> 79 >>> User('john', 'john@example.com', firstname="John") # actual call 80 81 .. versionadded:: 2.4.0 82 83 .. attribute:: exclude 84 85 While writing a :class:`Factory` for some object, it may be useful to 86 have general fields helping defining others, but that should not be 87 passed to the model class; for instance, a field named 'now' that would 88 hold a reference time used by other objects. 89 90 Factory fields whose name are listed in :attr:`exclude` will 91 be removed from the set of args/kwargs passed to the underlying class; 92 they can be any valid factory_boy declaration: 93 94 .. code-block:: python 95 96 class OrderFactory(factory.Factory): 97 class Meta: 98 model = Order 99 exclude = ('now',) 100 101 now = factory.LazyFunction(datetime.datetime.utcnow) 102 started_at = factory.LazyAttribute(lambda o: o.now - datetime.timedelta(hours=1)) 103 paid_at = factory.LazyAttribute(lambda o: o.now - datetime.timedelta(minutes=50)) 104 105 .. code-block:: pycon 106 107 >>> OrderFactory() # The value of 'now' isn't passed to Order() 108 <Order: started 2013-04-01 12:00:00, paid 2013-04-01 12:10:00> 109 110 >>> # An alternate value may be passed for 'now' 111 >>> OrderFactory(now=datetime.datetime(2013, 4, 1, 10)) 112 <Order: started 2013-04-01 09:00:00, paid 2013-04-01 09:10:00> 113 114 .. versionadded:: 2.4.0 115 116 117 .. attribute:: rename 118 119 Sometimes, a model expects a field with a name already used by one 120 of :class:`Factory`'s methods. 121 122 In this case, the :attr:`rename` attributes allows to define renaming 123 rules: the keys of the :attr:`rename` dict are those used in the 124 :class:`Factory` declarations, and their values the new name: 125 126 .. code-block:: python 127 128 class ImageFactory(factory.Factory): 129 # The model expects "attributes" 130 form_attributes = ['thumbnail', 'black-and-white'] 131 132 class Meta: 133 model = Image 134 rename = {'form_attributes': 'attributes'} 135 136 .. versionadded: 2.6.0 137 138 139 .. attribute:: strategy 140 141 Use this attribute to change the strategy used by a :class:`Factory`. 142 The default is :data:`CREATE_STRATEGY`. 143 144 145 146Attributes and methods 147"""""""""""""""""""""" 148 149 150.. class:: Factory 151 152 153 **Class-level attributes:** 154 155 .. attribute:: Meta 156 .. attribute:: _meta 157 158 .. versionadded:: 2.4.0 159 160 The :class:`FactoryOptions` instance attached to a :class:`Factory` class is available 161 as a :attr:`_meta` attribute. 162 163 .. attribute:: Params 164 165 .. versionadded:: 2.7.0 166 167 The extra parameters attached to a :class:`Factory` are declared through a :attr:`Params` 168 class. 169 See :ref:`the "Parameters" section <parameters>` for more information. 170 171 .. attribute:: _options_class 172 173 .. versionadded:: 2.4.0 174 175 If a :class:`Factory` subclass needs to define additional, extra options, it has to 176 provide a custom :class:`FactoryOptions` subclass. 177 178 A pointer to that custom class should be provided as :attr:`_options_class` so that 179 the :class:`Factory`-building metaclass can use it instead. 180 181 182 **Base functions:** 183 184 The :class:`Factory` class provides a few methods for getting objects; 185 the usual way being to simply call the class: 186 187 .. code-block:: pycon 188 189 >>> UserFactory() # Calls UserFactory.create() 190 >>> UserFactory(login='john') # Calls UserFactory.create(login='john') 191 192 Under the hood, factory_boy will define the :class:`Factory` 193 :meth:`~object.__new__` method to call the default :ref:`strategy <strategies>` 194 of the :class:`Factory`. 195 196 197 A specific strategy for getting instance can be selected by calling the 198 adequate method: 199 200 .. classmethod:: build(cls, **kwargs) 201 202 Provides a new object, using the 'build' strategy. 203 204 .. classmethod:: build_batch(cls, size, **kwargs) 205 206 Provides a list of :obj:`size` instances from the :class:`Factory`, 207 through the 'build' strategy. 208 209 210 .. classmethod:: create(cls, **kwargs) 211 212 Provides a new object, using the 'create' strategy. 213 214 .. classmethod:: create_batch(cls, size, **kwargs) 215 216 Provides a list of :obj:`size` instances from the :class:`Factory`, 217 through the 'create' strategy. 218 219 220 .. classmethod:: stub(cls, **kwargs) 221 222 Provides a new stub 223 224 .. classmethod:: stub_batch(cls, size, **kwargs) 225 226 Provides a list of :obj:`size` stubs from the :class:`Factory`. 227 228 229 .. classmethod:: generate(cls, strategy, **kwargs) 230 231 Provide a new instance, with the provided :obj:`strategy`. 232 233 .. classmethod:: generate_batch(cls, strategy, size, **kwargs) 234 235 Provides a list of :obj:`size` instances using the specified strategy. 236 237 238 .. classmethod:: simple_generate(cls, create, **kwargs) 239 240 Provide a new instance, either built (``create=False``) or created (``create=True``). 241 242 .. classmethod:: simple_generate_batch(cls, create, size, **kwargs) 243 244 Provides a list of :obj:`size` instances, either built or created 245 according to :obj:`create`. 246 247 248 **Extension points:** 249 250 A :class:`Factory` subclass may override a couple of class methods to adapt 251 its behavior: 252 253 .. classmethod:: _adjust_kwargs(cls, **kwargs) 254 255 .. OHAI_VIM** 256 257 The :meth:`_adjust_kwargs` extension point allows for late fields tuning. 258 259 It is called once keyword arguments have been resolved and post-generation 260 items removed, but before the :attr:`~FactoryOptions.inline_args` extraction 261 phase. 262 263 .. code-block:: python 264 265 class UserFactory(factory.Factory): 266 267 @classmethod 268 def _adjust_kwargs(cls, **kwargs): 269 # Ensure ``lastname`` is upper-case. 270 kwargs['lastname'] = kwargs['lastname'].upper() 271 return kwargs 272 273 .. OHAI_VIM** 274 275 .. classmethod:: _setup_next_sequence(cls) 276 277 This method will compute the first value to use for the sequence counter 278 of this factory. 279 280 It is called when the first instance of the factory (or one of its subclasses) 281 is created. 282 283 Subclasses may fetch the next free ID from the database, for instance. 284 285 286 .. classmethod:: _build(cls, model_class, *args, **kwargs) 287 288 .. OHAI_VIM* 289 290 This class method is called whenever a new instance needs to be built. 291 It receives the model class (provided to :attr:`~FactoryOptions.model`), and 292 the positional and keyword arguments to use for the class once all has 293 been computed. 294 295 Subclasses may override this for custom APIs. 296 297 298 .. classmethod:: _create(cls, model_class, *args, **kwargs) 299 300 .. OHAI_VIM* 301 302 The :meth:`_create` method is called whenever an instance needs to be 303 created. 304 It receives the same arguments as :meth:`_build`. 305 306 Subclasses may override this for specific persistence backends: 307 308 .. code-block:: python 309 310 class BaseBackendFactory(factory.Factory): 311 class Meta: 312 abstract = True # Optional 313 314 @classmethod 315 def _create(cls, model_class, *args, **kwargs): 316 obj = model_class(*args, **kwargs) 317 obj.save() 318 return obj 319 320 .. OHAI_VIM* 321 322 .. classmethod:: _after_postgeneration(cls, obj, create, results=None) 323 324 :arg object obj: The object just generated 325 :arg bool create: Whether the object was 'built' or 'created' 326 :arg dict results: Map of post-generation declaration name to call 327 result 328 329 The :meth:`_after_postgeneration` is called once post-generation 330 declarations have been handled. 331 332 Its arguments allow to handle specifically some post-generation return 333 values, for instance. 334 335 336 **Advanced functions:** 337 338 339 .. classmethod:: reset_sequence(cls, value=None, force=False) 340 341 :arg int value: The value to reset the sequence to 342 :arg bool force: Whether to force-reset the sequence 343 344 Allows to reset the sequence counter for a :class:`~factory.Factory`. 345 The new value can be passed in as the ``value`` argument: 346 347 .. code-block:: pycon 348 349 >>> SomeFactory.build().sequenced_attribute 350 0 351 >>> SomeFactory.reset_sequence(4) 352 >>> SomeFactory.build().sequenced_attribute 353 4 354 355 Since subclasses of a non-:attr:`abstract <factory.FactoryOptions.abstract>` 356 :class:`~factory.Factory` share the same sequence counter, special care needs 357 to be taken when resetting the counter of such a subclass. 358 359 By default, :meth:`reset_sequence` will raise a :exc:`ValueError` when 360 called on a subclassed :class:`~factory.Factory` subclass. This can be 361 avoided by passing in the ``force=True`` flag: 362 363 .. code-block:: pycon 364 365 >>> InheritedFactory.reset_sequence() 366 Traceback (most recent call last): 367 File "factory_boy/tests/test_base.py", line 179, in test_reset_sequence_subclass_parent 368 SubTestObjectFactory.reset_sequence() 369 File "factory_boy/factory/base.py", line 250, in reset_sequence 370 "Cannot reset the sequence of a factory subclass. " 371 ValueError: Cannot reset the sequence of a factory subclass. Please call reset_sequence() on the root factory, or call reset_sequence(forward=True). 372 373 >>> InheritedFactory.reset_sequence(force=True) 374 >>> 375 376 This is equivalent to calling :meth:`reset_sequence` on the base 377 factory in the chain. 378 379 380.. _parameters: 381 382Parameters 383"""""""""" 384 385.. versionadded:: 2.7.0 386 387Some models have many fields that can be summarized by a few parameters; for instance, 388a train with many cars — each complete with serial number, manufacturer, ...; 389or an order that can be pending/shipped/received, with a few fields to describe each step. 390 391When building instances of such models, a couple of parameters can be enough to determine 392all other fields; this is handled by the :class:`~Factory.Params` section of a :class:`Factory` declaration. 393 394 395Simple parameters 396~~~~~~~~~~~~~~~~~ 397 398Some factories only need little data: 399 400.. code-block:: python 401 402 class ConferenceFactory(factory.Factory): 403 class Meta: 404 model = Conference 405 406 class Params: 407 duration = 'short' # Or 'long' 408 409 start_date = factory.fuzzy.FuzzyDate() 410 end_date = factory.LazyAttribute( 411 lambda o: o.start_date + datetime.timedelta(days=2 if o.duration == 'short' else 7) 412 ) 413 sprints_start = factory.LazyAttribute( 414 lambda o: o.end_date - datetime.timedelta(days=0 if o.duration == 'short' else 1) 415 ) 416 417.. code-block:: pycon 418 419 >>> ConferenceFactory(duration='short') 420 <Conference: DUTH 2015 (2015-11-05 - 2015-11-08, sprints 2015-11-08)> 421 >>> ConferenceFactory(duration='long') 422 <Conference: DjangoConEU 2016 (2016-03-30 - 2016-04-03, sprints 2016-04-02)> 423 424 425Any simple parameter provided to the :class:`Factory.Params` section is available to the whole factory, 426but not passed to the final class (similar to the :attr:`~FactoryOptions.exclude` behavior). 427 428 429Traits 430~~~~~~ 431 432.. class:: Trait(**kwargs) 433 434 .. OHAI VIM** 435 436 .. versionadded:: 2.7.0 437 438 A trait's parameters are the fields it should alter when enabled. 439 440 441For more complex situations, it is helpful to override a few fields at once: 442 443.. code-block:: python 444 445 class OrderFactory(factory.Factory): 446 class Meta: 447 model = Order 448 449 state = 'pending' 450 shipped_on = None 451 shipped_by = None 452 453 class Params: 454 shipped = factory.Trait( 455 state='shipped', 456 shipped_on=datetime.date.today(), 457 shipped_by=factory.SubFactory(EmployeeFactory), 458 ) 459 460Such a :class:`Trait` is activated or disabled by a single boolean field: 461 462 463.. code-block:: pycon 464 465 >>> OrderFactory() 466 <Order: pending> 467 Order(state='pending') 468 >>> OrderFactory(shipped=True) 469 <Order: shipped by John Doe on 2016-04-02> 470 471 472A :class:`Trait` can be enabled/disabled by a :class:`Factory` subclass: 473 474.. code-block:: python 475 476 class ShippedOrderFactory(OrderFactory): 477 shipped = True 478 479 480Values set in a :class:`Trait` can be overridden by call-time values: 481 482.. code-block:: pycon 483 484 >>> OrderFactory(shipped=True, shipped_on=last_year) 485 <Order: shipped by John Doe on 2015-04-20> 486 487 488:class:`Traits <Trait>` can be chained: 489 490.. code-block:: python 491 492 class OrderFactory(factory.Factory): 493 class Meta: 494 model = Order 495 496 # Can be pending/shipping/received 497 state = 'pending' 498 shipped_on = None 499 shipped_by = None 500 received_on = None 501 received_by = None 502 503 class Params: 504 shipped = factory.Trait( 505 state='shipped', 506 shipped_on=datetime.date.today, 507 shipped_by=factory.SubFactory(EmployeeFactory), 508 ) 509 received = factory.Trait( 510 shipped=True, 511 state='received', 512 shipped_on=datetime.date.today - datetime.timedelta(days=4), 513 received_on=datetime.date.today, 514 received_by=factory.SubFactory(CustomerFactory), 515 ) 516 517.. code-block:: pycon 518 519 >>> OrderFactory(received=True) 520 <Order: shipped by John Doe on 2016-03-20, received by Joan Smith on 2016-04-02> 521 522 523 524A :class:`Trait` might be overridden in :class:`Factory` subclasses: 525 526.. code-block:: python 527 528 class LocalOrderFactory(OrderFactory): 529 530 class Params: 531 received = factory.Trait( 532 shipped=True, 533 state='received', 534 shipped_on=datetime.date.today - datetime.timedelta(days=1), 535 received_on=datetime.date.today, 536 received_by=factory.SubFactory(CustomerFactory), 537 ) 538 539 540.. code-block:: pycon 541 542 >>> LocalOrderFactory(received=True) 543 <Order: shipped by John Doe on 2016-04-01, received by Joan Smith on 2016-04-02> 544 545 546.. note:: When overriding a :class:`Trait`, the whole declaration **MUST** be replaced. 547 548 549.. _strategies: 550 551Strategies 552"""""""""" 553 554factory_boy supports two main strategies for generating instances, plus stubs. 555 556 557.. data:: BUILD_STRATEGY 558 559 The 'build' strategy is used when an instance should be created, 560 but not persisted to any datastore. 561 562 It is usually a simple call to the :meth:`~object.__init__` method of the 563 :attr:`~FactoryOptions.model` class. 564 565 566.. data:: CREATE_STRATEGY 567 568 The 'create' strategy builds and saves an instance into its appropriate datastore. 569 570 This is the default strategy of factory_boy; it would typically instantiate an 571 object, then save it: 572 573 .. code-block:: pycon 574 575 >>> obj = self._associated_class(*args, **kwargs) 576 >>> obj.save() 577 >>> return obj 578 579 .. OHAI_VIM* 580 581 .. warning:: For backward compatibility reasons, the default behavior of 582 factory_boy is to call ``MyClass.objects.create(*args, **kwargs)`` 583 when using the ``create`` strategy. 584 585 That policy will be used if the 586 :attr:`associated class <FactoryOptions.model>` has an ``objects`` 587 attribute *and* the :meth:`~Factory._create` classmethod of the 588 :class:`Factory` wasn't overridden. 589 590 591.. function:: use_strategy(strategy) 592 593 .. deprecated:: 3.2 594 595 Use :py:attr:`factory.FactoryOptions.strategy` instead. 596 597 *Decorator* 598 599 Change the default strategy of the decorated :class:`Factory` to the chosen :obj:`strategy`: 600 601 .. code-block:: python 602 603 @use_strategy(factory.BUILD_STRATEGY) 604 class UserBuildingFactory(UserFactory): 605 pass 606 607 608.. data:: STUB_STRATEGY 609 610 The 'stub' strategy is an exception in the factory_boy world: it doesn't return 611 an instance of the :attr:`~FactoryOptions.model` class, and actually doesn't 612 require one to be present. 613 614 Instead, it returns an instance of :class:`StubObject` whose attributes have been 615 set according to the declarations. 616 617 618.. class:: StubObject 619 620 A plain, stupid object. No method, no helpers, simply a bunch of attributes. 621 622 It is typically instantiated, then has its attributes set: 623 624 .. code-block:: pycon 625 626 >>> obj = StubObject() 627 >>> obj.x = 1 628 >>> obj.y = 2 629 630 631.. class:: StubFactory(Factory) 632 633 An :attr:`abstract <FactoryOptions.abstract>` :class:`Factory`, 634 with a default strategy set to :data:`STUB_STRATEGY`. 635 636 637.. function:: debug(logger='factory', stream=None) 638 639 :param str logger: The name of the logger to enable debug for 640 :param file stream: The stream to send debug output to, defaults to :obj:`sys.stderr` 641 642 Context manager to help debugging factory_boy behavior. 643 It will temporarily put the target logger (e.g ``'factory'``) in debug mode, 644 sending all output to ``stream``; 645 upon leaving the context, the logging levels are reset. 646 647 A typical use case is to understand what happens during a single factory call: 648 649 .. code-block:: python 650 651 with factory.debug(): 652 obj = TestModel2Factory() 653 654 This will yield messages similar to those (artificial indentation): 655 656 .. code-block:: ini 657 658 BaseFactory: Preparing tests.test_using.TestModel2Factory(extra={}) 659 LazyStub: Computing values for tests.test_using.TestModel2Factory(two=<OrderedDeclarationWrapper for <factory.declarations.SubFactory object at 0x1e15610>>) 660 SubFactory: Instantiating tests.test_using.TestModelFactory(__containers=(<LazyStub for tests.test_using.TestModel2Factory>,), one=4), create=True 661 BaseFactory: Preparing tests.test_using.TestModelFactory(extra={'__containers': (<LazyStub for tests.test_using.TestModel2Factory>,), 'one': 4}) 662 LazyStub: Computing values for tests.test_using.TestModelFactory(one=4) 663 LazyStub: Computed values, got tests.test_using.TestModelFactory(one=4) 664 BaseFactory: Generating tests.test_using.TestModelFactory(one=4) 665 LazyStub: Computed values, got tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>) 666 BaseFactory: Generating tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>) 667 668 669.. _declarations: 670 671Declarations 672------------ 673 674 675Faker 676""""" 677 678.. class:: Faker(provider, locale=None, **kwargs) 679 680 .. OHAIVIM** 681 682 In order to easily define realistic-looking factories, 683 use the :class:`Faker` attribute declaration. 684 685 This is a wrapper around `faker <https://faker.readthedocs.io/en/latest/>`_; 686 its argument is the name of a ``faker`` provider: 687 688 .. code-block:: python 689 690 class UserFactory(factory.Factory): 691 class Meta: 692 model = User 693 694 name = factory.Faker('name') 695 696 .. code-block:: pycon 697 698 >>> user = UserFactory() 699 >>> user.name 700 'Lucy Cechtelar' 701 702 Some providers accept parameters; they should be passed after the provider name: 703 704 .. code-block:: python 705 706 class UserFactory(fatory.Factory): 707 class Meta: 708 model = User 709 710 arrival = factory.Faker( 711 'date_between_dates', 712 date_start=datetime.date(2020, 1, 1), 713 date_end=datetime.date(2020, 5, 31), 714 ) 715 716 As with :class:`~factory.SubFactory`, the parameters can be any valid declaration. 717 This does not apply to the provider name or the locale. 718 719 .. code-block:: python 720 721 class TripFactory(fatory.Factory): 722 class Meta: 723 model = Trip 724 725 departure = factory.Faker( 726 'date', 727 end_datetime=datetime.date.today(), 728 ) 729 arrival = factory.Faker( 730 'date_between_dates', 731 date_start=factory.SelfAttribute('..departure'), 732 ) 733 734 .. note:: When using :class:`~factory.SelfAttribute` or :class:`~factory.LazyAttribute` 735 in a :class:`factory.Faker` parameter, the current object is the declarations 736 provided to the :class:`~factory.Faker` declaration; go :ref:`up a level <factory-parent>` 737 to reach fields of the surrounding :class:`~factory.Factory`, as shown 738 in the ``SelfAttribute('..xxx')`` example above. 739 740 .. attribute:: locale 741 742 If a custom locale is required for one specific field, 743 use the ``locale`` parameter: 744 745 .. code-block:: python 746 747 class UserFactory(factory.Factory): 748 class Meta: 749 model = User 750 751 name = factory.Faker('name', locale='fr_FR') 752 753 .. code-block:: pycon 754 755 >>> user = UserFactory() 756 >>> user.name 757 'Jean Valjean' 758 759 760 .. classmethod:: override_default_locale(cls, locale) 761 762 If the locale needs to be overridden for a whole test, 763 use :meth:`~factory.Faker.override_default_locale`: 764 765 .. code-block:: pycon 766 767 >>> with factory.Faker.override_default_locale('de_DE'): 768 ... UserFactory() 769 <User: Johannes Brahms> 770 771 .. classmethod:: add_provider(cls, locale=None) 772 773 Some projects may need to fake fields beyond those provided by ``faker``; 774 in such cases, use :meth:`factory.Faker.add_provider` to declare additional providers 775 for those fields: 776 777 .. code-block:: python 778 779 factory.Faker.add_provider(SmileyProvider) 780 781 class FaceFactory(factory.Factory): 782 class Meta: 783 model = Face 784 785 smiley = factory.Faker('smiley') 786 787 788LazyFunction 789"""""""""""" 790 791.. class:: LazyFunction(method_to_call) 792 793The :class:`LazyFunction` is the simplest case where the value of an attribute 794does not depend on the object being built. 795 796It takes as an argument a function to call; that should not take any arguments and 797return a value. 798 799.. code-block:: python 800 801 class LogFactory(factory.Factory): 802 class Meta: 803 model = models.Log 804 805 timestamp = factory.LazyFunction(datetime.now) 806 807.. code-block:: pycon 808 809 >>> LogFactory() 810 <Log: log at 2016-02-12 17:02:34> 811 812 >>> # The LazyFunction can be overridden 813 >>> LogFactory(timestamp=now - timedelta(days=1)) 814 <Log: log at 2016-02-11 17:02:34> 815 816:class:`LazyFunction` is also useful for assigning copies of mutable objects 817(like lists) to an object's property. Example: 818 819.. code-block:: python 820 821 DEFAULT_TEAM = ['Player1', 'Player2'] 822 823 class TeamFactory(factory.Factory): 824 class Meta: 825 model = models.Team 826 827 teammates = factory.LazyFunction(lambda: list(DEFAULT_TEAM)) 828 829 830Decorator 831~~~~~~~~~ 832 833The class :class:`LazyFunction` does not provide a decorator. 834 835For complex cases, use :meth:`LazyAttribute.lazy_attribute` directly. 836 837LazyAttribute 838""""""""""""" 839 840.. class:: LazyAttribute(method_to_call) 841 842The :class:`LazyAttribute` is a simple yet extremely powerful building brick 843for extending a :class:`Factory`. 844 845It takes as argument a method to call (usually a lambda); that method should 846accept the object being built as sole argument, and return a value. 847 848.. code-block:: python 849 850 class UserFactory(factory.Factory): 851 class Meta: 852 model = User 853 854 username = 'john' 855 email = factory.LazyAttribute(lambda o: '%s@example.com' % o.username) 856 857.. code-block:: pycon 858 859 >>> u = UserFactory() 860 >>> u.email 861 'john@example.com' 862 863 >>> u = UserFactory(username='leo') 864 >>> u.email 865 'leo@example.com' 866 867 868The object passed to :class:`LazyAttribute` is not an instance of the target class, 869but instead a :class:`~builder.Resolver`: a temporary container that computes 870the value of all declared fields. 871 872 873Decorator 874~~~~~~~~~ 875 876.. function:: lazy_attribute 877 878If a simple lambda isn't enough, you may use the :meth:`lazy_attribute` decorator instead. 879 880This decorates an instance method that should take a single argument, ``self``; 881the name of the method will be used as the name of the attribute to fill with the 882return value of the method: 883 884.. code-block:: python 885 886 class UserFactory(factory.Factory) 887 class Meta: 888 model = User 889 890 name = "Jean" 891 892 @factory.lazy_attribute 893 def email(self): 894 # Convert to plain ascii text 895 clean_name = (unicodedata.normalize('NFKD', self.name) 896 .encode('ascii', 'ignore') 897 .decode('utf8')) 898 return '%s@example.com' % clean_name 899 900.. code-block:: pycon 901 902 >>> joel = UserFactory(name="Joël") 903 >>> joel.email 904 'joel@example.com' 905 906 907Sequence 908"""""""" 909 910.. class:: Sequence(lambda) 911 912If a field should be unique, and thus different for all built instances, 913use a :class:`Sequence`. 914 915This declaration takes a single argument, a function accepting a single parameter 916- the current sequence counter - and returning the related value. 917 918.. code-block:: python 919 920 class UserFactory(factory.Factory) 921 class Meta: 922 model = User 923 924 phone = factory.Sequence(lambda n: '123-555-%04d' % n) 925 926.. code-block:: pycon 927 928 >>> UserFactory().phone 929 '123-555-0001' 930 >>> UserFactory().phone 931 '123-555-0002' 932 933 934Decorator 935~~~~~~~~~ 936 937.. function:: sequence 938 939As with :meth:`lazy_attribute`, a decorator is available for complex situations. 940 941:meth:`sequence` decorates an instance method, whose ``self`` method will actually 942be the sequence counter - this might be confusing: 943 944.. code-block:: python 945 946 class UserFactory(factory.Factory) 947 class Meta: 948 model = User 949 950 @factory.sequence 951 def phone(n): 952 a = n // 10000 953 b = n % 10000 954 return '%03d-555-%04d' % (a, b) 955 956.. code-block:: pycon 957 958 >>> UserFactory().phone 959 '000-555-9999' 960 >>> UserFactory().phone 961 '001-555-0000' 962 963 964Sharing 965~~~~~~~ 966 967The sequence counter is shared across all :class:`Sequence` attributes of the 968:class:`Factory`: 969 970.. code-block:: python 971 972 class UserFactory(factory.Factory): 973 class Meta: 974 model = User 975 976 phone = factory.Sequence(lambda n: '%04d' % n) 977 office = factory.Sequence(lambda n: 'A23-B%03d' % n) 978 979.. code-block:: pycon 980 981 >>> u = UserFactory() 982 >>> u.phone, u.office 983 '0041', 'A23-B041' 984 >>> u2 = UserFactory() 985 >>> u2.phone, u2.office 986 '0042', 'A23-B042' 987 988 989Inheritance 990~~~~~~~~~~~ 991 992When a :class:`Factory` inherits from another :class:`Factory` and the `model` 993of the subclass inherits from the `model` of the parent, the sequence counter 994is shared across the :class:`Factory` classes: 995 996.. code-block:: python 997 998 class UserFactory(factory.Factory): 999 class Meta: 1000 model = User 1001 1002 phone = factory.Sequence(lambda n: '123-555-%04d' % n) 1003 1004 1005 class EmployeeFactory(UserFactory): 1006 office_phone = factory.Sequence(lambda n: '%04d' % n) 1007 1008.. code-block:: pycon 1009 1010 >>> u = UserFactory() 1011 >>> u.phone 1012 '123-555-0001' 1013 1014 >>> e = EmployeeFactory() 1015 >>> e.phone, e.office_phone 1016 '123-555-0002', '0002' 1017 1018 >>> u2 = UserFactory() 1019 >>> u2.phone 1020 '123-555-0003' 1021 1022 1023Forcing a sequence counter 1024~~~~~~~~~~~~~~~~~~~~~~~~~~ 1025 1026If a specific value of the sequence counter is required for one instance, the 1027``__sequence`` keyword argument should be passed to the factory method. 1028 1029This will force the sequence counter during the call, without altering the 1030class-level value. 1031 1032.. code-block:: python 1033 1034 class UserFactory(factory.Factory): 1035 class Meta: 1036 model = User 1037 1038 uid = factory.Sequence(int) 1039 1040.. code-block:: pycon 1041 1042 >>> UserFactory() 1043 <User: 0> 1044 >>> UserFactory() 1045 <User: 1> 1046 >>> UserFactory(__sequence=42) 1047 <User: 42> 1048 1049 1050.. warning:: The impact of setting ``__sequence=n`` on a ``_batch`` call is 1051 undefined. Each generated instance may share a same counter, or 1052 use incremental values starting from the forced value. 1053 1054 1055LazyAttributeSequence 1056""""""""""""""""""""" 1057 1058.. class:: LazyAttributeSequence(method_to_call) 1059 1060The :class:`LazyAttributeSequence` declaration merges features of :class:`Sequence` 1061and :class:`LazyAttribute`. 1062 1063It takes a single argument, a function whose two parameters are, in order: 1064 1065* The object being built 1066* The sequence counter 1067 1068.. code-block:: python 1069 1070 class UserFactory(factory.Factory): 1071 class Meta: 1072 model = User 1073 1074 login = 'john' 1075 email = factory.LazyAttributeSequence(lambda o, n: '%s@s%d.example.com' % (o.login, n)) 1076 1077.. code-block:: pycon 1078 1079 >>> UserFactory().email 1080 'john@s1.example.com' 1081 >>> UserFactory(login='jack').email 1082 'jack@s2.example.com' 1083 1084 1085Decorator 1086~~~~~~~~~ 1087 1088.. function:: lazy_attribute_sequence(method_to_call) 1089 1090As for :meth:`lazy_attribute` and :meth:`sequence`, the :meth:`lazy_attribute_sequence` 1091handles more complex cases: 1092 1093.. code-block:: python 1094 1095 class UserFactory(factory.Factory): 1096 class Meta: 1097 model = User 1098 1099 login = 'john' 1100 1101 @lazy_attribute_sequence 1102 def email(self, n): 1103 bucket = n % 10 1104 return '%s@s%d.example.com' % (self.login, bucket) 1105 1106 1107SubFactory 1108"""""""""" 1109 1110.. class:: SubFactory(factory, **kwargs) 1111 1112 .. OHAI_VIM** 1113 1114This attribute declaration calls another :class:`Factory` subclass, 1115selecting the same build strategy and collecting extra kwargs in the process. 1116 1117The :class:`SubFactory` attribute should be called with: 1118 1119* A :class:`Factory` subclass as first argument, or the fully qualified import 1120 path to that :class:`Factory` (see :ref:`Circular imports <subfactory-circular>`) 1121* An optional set of keyword arguments that should be passed when calling that 1122 factory 1123 1124 1125.. note:: 1126 1127 When passing an actual :class:`~factory.Factory` for the 1128 :attr:`~factory.SubFactory.factory` argument, make sure to pass 1129 the class and not instance (i.e no ``()`` after the class): 1130 1131 .. code-block:: python 1132 1133 class FooFactory(factory.Factory): 1134 class Meta: 1135 model = Foo 1136 1137 bar = factory.SubFactory(BarFactory) # Not BarFactory() 1138 1139 1140Definition 1141~~~~~~~~~~ 1142 1143.. code-block:: python 1144 1145 1146 # A standard factory 1147 class UserFactory(factory.Factory): 1148 class Meta: 1149 model = User 1150 1151 # Various fields 1152 first_name = 'John' 1153 last_name = factory.Sequence(lambda n: 'D%se' % ('o' * n)) # De, Doe, Dooe, Doooe, ... 1154 email = factory.LazyAttribute(lambda o: '%s.%s@example.org' % (o.first_name.lower(), o.last_name.lower())) 1155 1156 # A factory for an object with a 'User' field 1157 class CompanyFactory(factory.Factory): 1158 class Meta: 1159 model = Company 1160 1161 name = factory.Sequence(lambda n: 'FactoryBoyz' + 'z' * n) 1162 1163 # Let's use our UserFactory to create that user, and override its first name. 1164 owner = factory.SubFactory(UserFactory, first_name='Jack') 1165 1166 1167Calling 1168~~~~~~~ 1169 1170The wrapping factory will call of the inner factory: 1171 1172.. code-block:: pycon 1173 1174 >>> c = CompanyFactory() 1175 >>> c 1176 <Company: FactoryBoyz> 1177 1178 # Notice that the first_name was overridden 1179 >>> c.owner 1180 <User: Jack De> 1181 >>> c.owner.email 1182 jack.de@example.org 1183 1184 1185Fields of the :class:`~factory.SubFactory` may be overridden from the external factory: 1186 1187.. code-block:: pycon 1188 1189 >>> c = CompanyFactory(owner__first_name='Henry') 1190 >>> c.owner 1191 <User: Henry Doe> 1192 1193 # Notice that the updated first_name was propagated to the email LazyAttribute. 1194 >>> c.owner.email 1195 henry.doe@example.org 1196 1197 # It is also possible to override other fields of the SubFactory 1198 >>> c = CompanyFactory(owner__last_name='Jones') 1199 >>> c.owner 1200 <User: Henry Jones> 1201 >>> c.owner.email 1202 henry.jones@example.org 1203 1204 1205Strategies 1206~~~~~~~~~~ 1207 1208The strategy chosen for the external factory will be propagated to all subfactories: 1209 1210.. code-block:: pycon 1211 1212 >>> c = CompanyFactory() 1213 >>> c.pk # Saved to the database 1214 3 1215 >>> c.owner.pk # Saved to the database 1216 8 1217 1218 >>> c = CompanyFactory.build() 1219 >>> c.pk # Not saved 1220 None 1221 >>> c.owner.pk # Not saved either 1222 None 1223 1224 1225.. _subfactory-circular: 1226 1227Circular imports 1228~~~~~~~~~~~~~~~~ 1229 1230Some factories may rely on each other in a circular manner. 1231This issue can be handled by passing the absolute import path to the target 1232:class:`Factory` to the :class:`SubFactory`. 1233 1234.. versionadded:: 1.3.0 1235 1236.. code-block:: python 1237 1238 class UserFactory(factory.Factory): 1239 class Meta: 1240 model = User 1241 1242 username = 'john' 1243 main_group = factory.SubFactory('users.factories.GroupFactory') 1244 1245 class GroupFactory(factory.Factory): 1246 class Meta: 1247 model = Group 1248 1249 name = "MyGroup" 1250 owner = factory.SubFactory(UserFactory) 1251 1252 1253Obviously, such circular relationships require careful handling of loops: 1254 1255.. code-block:: pycon 1256 1257 >>> owner = UserFactory(main_group=None) 1258 >>> UserFactory(main_group__owner=owner) 1259 <john (group: MyGroup)> 1260 1261 1262SelfAttribute 1263""""""""""""" 1264 1265.. class:: SelfAttribute(dotted_path_to_attribute) 1266 1267Some fields should reference another field of the object being constructed, or an attribute thereof. 1268 1269This is performed by the :class:`~factory.SelfAttribute` declaration. 1270That declaration takes a single argument, a dot-delimited path to the attribute to fetch: 1271 1272.. code-block:: python 1273 1274 class UserFactory(factory.Factory): 1275 class Meta: 1276 model = User 1277 1278 birthdate = factory.Sequence(lambda n: datetime.date(2000, 1, 1) + datetime.timedelta(days=n)) 1279 birthmonth = factory.SelfAttribute('birthdate.month') 1280 1281.. code-block:: pycon 1282 1283 >>> u = UserFactory() 1284 >>> u.birthdate 1285 date(2000, 3, 15) 1286 >>> u.birthmonth 1287 3 1288 1289 1290.. _factory-parent: 1291 1292Parents 1293~~~~~~~ 1294 1295When used in conjunction with :class:`~factory.SubFactory`, the :class:`~factory.SelfAttribute` 1296gains an "upward" semantic through the double-dot notation, as used in Python imports. 1297 1298``factory.SelfAttribute('..country.language')`` means 1299"Select the ``language`` of the ``country`` of the :class:`~factory.Factory` calling me". 1300 1301.. code-block:: python 1302 1303 class UserFactory(factory.Factory): 1304 class Meta: 1305 model = User 1306 1307 language = 'en' 1308 1309 1310 class CompanyFactory(factory.Factory): 1311 class Meta: 1312 model = Company 1313 1314 country = factory.SubFactory(CountryFactory) 1315 owner = factory.SubFactory(UserFactory, language=factory.SelfAttribute('..country.language')) 1316 1317.. code-block:: pycon 1318 1319 >>> company = CompanyFactory() 1320 >>> company.country.language 1321 'fr' 1322 >>> company.owner.language 1323 'fr' 1324 1325Obviously, this "follow parents" ability also handles overriding some attributes on call: 1326 1327.. code-block:: pycon 1328 1329 >>> company = CompanyFactory(country=china) 1330 >>> company.owner.language 1331 'cn' 1332 1333 1334This feature is also available to :class:`LazyAttribute` and :class:`LazyAttributeSequence`, 1335through the :attr:`~builder.Resolver.factory_parent` attribute of the passed-in object: 1336 1337.. code-block:: python 1338 1339 class CompanyFactory(factory.Factory): 1340 class Meta: 1341 model = Company 1342 country = factory.SubFactory(CountryFactory) 1343 owner = factory.SubFactory(UserFactory, 1344 language=factory.LazyAttribute(lambda user: user.factory_parent.country.language), 1345 ) 1346 1347 1348Iterator 1349"""""""" 1350 1351.. class:: Iterator(iterable, cycle=True, getter=None) 1352 1353 The :class:`Iterator` declaration takes successive values from the given 1354 iterable. When it is exhausted, it starts again from zero (unless ``cycle=False``). 1355 1356 .. attribute:: cycle 1357 1358 The ``cycle`` argument is only useful for advanced cases, where the provided 1359 iterable has no end (as wishing to cycle it means storing values in memory...). 1360 1361 .. versionadded:: 1.3.0 1362 The ``cycle`` argument is available as of v1.3.0; previous versions 1363 had a behavior equivalent to ``cycle=False``. 1364 1365 .. attribute:: getter 1366 1367 A custom function called on each value returned by the iterable. 1368 See the :ref:`iterator-getter` section for details. 1369 1370 .. versionadded:: 1.3.0 1371 1372 .. method:: reset() 1373 1374 Reset the internal iterator used by the attribute, so that the next value 1375 will be the first value generated by the iterator. 1376 1377 May be called several times. 1378 1379 1380Each call to the factory will receive the next value from the iterable: 1381 1382.. code-block:: python 1383 1384 class UserFactory(factory.Factory) 1385 lang = factory.Iterator(['en', 'fr', 'es', 'it', 'de']) 1386 1387.. code-block:: pycon 1388 1389 >>> UserFactory().lang 1390 'en' 1391 >>> UserFactory().lang 1392 'fr' 1393 1394 1395When a value is passed in for the argument, the iterator will *not* be advanced: 1396 1397.. code-block:: pycon 1398 1399 >>> UserFactory().lang 1400 'en' 1401 >>> UserFactory(lang='cn').lang 1402 'cn' 1403 >>> UserFactory().lang 1404 'fr' 1405 1406 1407.. _iterator-getter: 1408 1409Getter 1410~~~~~~ 1411 1412Some situations may reuse an existing iterable, using only some component. 1413This is handled by the :attr:`~Iterator.getter` attribute: this is a function 1414that accepts as sole parameter a value from the iterable, and returns an 1415adequate value. 1416 1417.. code-block:: python 1418 1419 class UserFactory(factory.Factory): 1420 class Meta: 1421 model = User 1422 1423 # CATEGORY_CHOICES is a list of (key, title) tuples 1424 category = factory.Iterator(User.CATEGORY_CHOICES, getter=lambda c: c[0]) 1425 1426 1427Decorator 1428~~~~~~~~~ 1429 1430.. function:: iterator(func) 1431 1432 1433When generating items of the iterator gets too complex for a simple list comprehension, 1434use the :func:`iterator` decorator: 1435 1436.. warning:: The decorated function takes **no** argument, 1437 notably no ``self`` parameter. 1438 1439.. code-block:: python 1440 1441 class UserFactory(factory.Factory): 1442 class Meta: 1443 model = User 1444 1445 @factory.iterator 1446 def name(): 1447 with open('test/data/names.dat', 'r') as f: 1448 for line in f: 1449 yield line 1450 1451 1452.. warning:: Values from the underlying iterator are *kept* in memory; once the 1453 initial iterator has been emptied, saved values are used instead of 1454 executing the function instead. 1455 1456 Use ``factory.Iterator(my_func, cycle=False)`` to disable value 1457 recycling. 1458 1459 1460 1461Resetting 1462~~~~~~~~~ 1463 1464In order to start back at the first value in an :class:`Iterator`, 1465simply call the :meth:`~Iterator.reset` method of that attribute 1466(accessing it from the bare :class:`~Factory` subclass): 1467 1468.. code-block:: pycon 1469 1470 >>> UserFactory().lang 1471 'en' 1472 >>> UserFactory().lang 1473 'fr' 1474 >>> UserFactory.lang.reset() 1475 >>> UserFactory().lang 1476 'en' 1477 1478 1479Dict and List 1480""""""""""""" 1481 1482When a factory expects lists or dicts as arguments, such values can be generated 1483through the whole range of factory_boy declarations, 1484with the :class:`Dict` and :class:`List` attributes: 1485 1486.. class:: Dict(params[, dict_factory=factory.DictFactory]) 1487 1488 The :class:`Dict` class is used for dict-like attributes. 1489 It receives as non-keyword argument a dictionary of fields to define, whose 1490 value may be any factory-enabled declarations: 1491 1492 .. code-block:: python 1493 1494 class UserFactory(factory.Factory): 1495 class Meta: 1496 model = User 1497 1498 is_superuser = False 1499 roles = factory.Dict({ 1500 'role1': True, 1501 'role2': False, 1502 'role3': factory.Iterator([True, False]), 1503 'admin': factory.SelfAttribute('..is_superuser'), 1504 }) 1505 1506 .. note:: Declarations used as a :class:`Dict` values are evaluated within 1507 that :class:`Dict`'s context; this means that you must use 1508 the ``..foo`` syntax to access fields defined at the factory level. 1509 1510 On the other hand, the :class:`Sequence` counter is aligned on the 1511 containing factory's one. 1512 1513 1514 The :class:`Dict` behavior can be tuned through the following parameters: 1515 1516 .. attribute:: dict_factory 1517 1518 The actual factory to use for generating the dict can be set as a keyword 1519 argument, if an exotic dictionary-like object (SortedDict, ...) is required. 1520 1521 1522.. class:: List(items[, list_factory=factory.ListFactory]) 1523 1524 The :class:`List` can be used for list-like attributes. 1525 1526 Internally, the fields are converted into a ``index=value`` dict, which 1527 makes it possible to override some values at use time: 1528 1529 .. code-block:: python 1530 1531 class UserFactory(factory.Factory): 1532 class Meta: 1533 model = User 1534 1535 flags = factory.List([ 1536 'user', 1537 'active', 1538 'admin', 1539 ]) 1540 1541 .. code-block:: pycon 1542 1543 >>> u = UserFactory(flags__2='superadmin') 1544 >>> u.flags 1545 ['user', 'active', 'superadmin'] 1546 1547 1548 The :class:`List` behavior can be tuned through the following parameters: 1549 1550 .. attribute:: list_factory 1551 1552 The actual factory to use for generating the list can be set as a keyword 1553 argument, if another type (tuple, set, ...) is required. 1554 1555 1556Maybe 1557""""" 1558 1559.. class:: Maybe(decider, yes_declaration, no_declaration) 1560 1561Sometimes, the way to build a given field depends on the value of another, 1562for instance of a parameter. 1563 1564In those cases, use the :class:`~factory.Maybe` declaration: 1565it takes the name of a "decider" boolean field, and two declarations; depending on 1566the value of the field whose name is held in the 'decider' parameter, it will 1567apply the effects of one or the other declaration: 1568 1569.. code-block:: python 1570 1571 class UserFactory(factory.Factory): 1572 class Meta: 1573 model = User 1574 1575 is_active = True 1576 deactivation_date = factory.Maybe( 1577 'is_active', 1578 yes_declaration=None, 1579 no_declaration=factory.fuzzy.FuzzyDateTime(timezone.now() - datetime.timedelta(days=10)), 1580 ) 1581 1582.. code-block:: pycon 1583 1584 >>> u = UserFactory(is_active=True) 1585 >>> u.deactivation_date 1586 None 1587 >>> u = UserFactory(is_active=False) 1588 >>> u.deactivation_date 1589 datetime.datetime(2017, 4, 1, 23, 21, 23, tzinfo=UTC) 1590 1591.. note:: If the condition for the decider is complex, use a :class:`LazyAttribute` 1592 defined in the :attr:`~Factory.Params` section of your factory to 1593 handle the computation. 1594 1595 1596Post-generation hooks 1597""""""""""""""""""""" 1598 1599Some objects expect additional method calls or complex processing for proper definition. 1600For instance, a ``User`` may need to have a related ``Profile``, where the ``Profile`` is built from the ``User`` object. 1601 1602To support this pattern, factory_boy provides the following tools: 1603 - :class:`PostGenerationMethodCall`: allows you to hook a particular attribute to a function call 1604 - :class:`PostGeneration`: this class allows calling a given function with the generated object as argument 1605 - :func:`post_generation`: decorator performing the same functions as :class:`PostGeneration` 1606 - :class:`RelatedFactory`: this builds or creates a given factory *after* building/creating the first Factory. 1607 - :class:`RelatedFactoryList`: this builds or creates a *list* of the given factory *after* building/creating the first Factory. 1608 1609Post-generation hooks are called in the same order they are declared in the factory class, so that 1610functions can rely on the side effects applied by the previous post-generation hook. 1611 1612 1613Extracting parameters 1614""""""""""""""""""""" 1615 1616All post-building hooks share a common base for picking parameters from the 1617set of attributes passed to the :class:`Factory`. 1618 1619For instance, a :class:`PostGeneration` hook is declared as ``post``: 1620 1621.. code-block:: python 1622 1623 class SomeFactory(factory.Factory): 1624 class Meta: 1625 model = SomeObject 1626 1627 @post_generation 1628 def post(obj, create, extracted, **kwargs): 1629 obj.set_origin(create) 1630 1631.. OHAI_VIM** 1632 1633 1634When calling the factory, some arguments will be extracted for this method: 1635 1636- If a ``post`` argument is passed, it will be passed as the ``extracted`` field 1637- Any argument starting with ``post__XYZ`` will be extracted, its ``post__`` prefix 1638 removed, and added to the kwargs passed to the post-generation hook. 1639 1640Extracted arguments won't be passed to the :attr:`~FactoryOptions.model` class. 1641 1642Thus, in the following call: 1643 1644.. code-block:: pycon 1645 1646 >>> SomeFactory( 1647 post=1, 1648 post_x=2, 1649 post__y=3, 1650 post__z__t=42, 1651 ) 1652 1653The ``post`` hook will receive ``1`` as ``extracted`` and ``{'y': 3, 'z__t': 42}`` 1654as keyword arguments; ``{'post_x': 2}`` will be passed to ``SomeFactory._meta.model``. 1655 1656 1657RelatedFactory 1658"""""""""""""" 1659 1660.. class:: RelatedFactory(factory, factory_related_name='', **kwargs) 1661 1662 .. OHAI_VIM** 1663 1664 A :class:`RelatedFactory` behaves mostly like a :class:`SubFactory`, 1665 with the main difference that the related :class:`Factory` will be generated 1666 *after* the base :class:`Factory`. 1667 1668 1669 .. attribute:: factory 1670 1671 As for :class:`SubFactory`, the :attr:`factory` argument can be: 1672 1673 - A :class:`Factory` subclass 1674 - Or the fully qualified path to a :class:`Factory` subclass 1675 (see :ref:`subfactory-circular` for details) 1676 1677 .. attribute:: factory_related_name 1678 1679 If set, the object generated by the factory declaring the 1680 ``RelatedFactory`` is passed as keyword argument to the related factory. 1681 1682.. code-block:: python 1683 1684 class CityFactory(factory.Factory): 1685 class Meta: 1686 model = City 1687 1688 capital_of = None 1689 name = "Toronto" 1690 1691 class CountryFactory(factory.Factory): 1692 class Meta: 1693 model = Country 1694 1695 lang = 'fr' 1696 capital_city = factory.RelatedFactory( 1697 CityFactory, # Not CityFactory() 1698 factory_related_name='capital_of', 1699 name="Paris", 1700 ) 1701 1702.. code-block:: pycon 1703 1704 >>> france = CountryFactory() 1705 >>> City.objects.get(capital_of=france) 1706 <City: Paris> 1707 1708 1709Extra kwargs may be passed to the related factory, through the usual ``ATTR__SUBATTR`` syntax: 1710 1711.. code-block:: pycon 1712 1713 >>> england = CountryFactory(lang='en', capital_city__name="London") 1714 >>> City.objects.get(capital_of=england) 1715 <City: London> 1716 1717If a value is passed for the :class:`RelatedFactory` attribute, this disables 1718:class:`RelatedFactory` generation: 1719 1720.. code-block:: pycon 1721 1722 >>> france = CountryFactory() 1723 >>> paris = City.objects.get() 1724 >>> paris 1725 <City: Paris> 1726 >>> reunion = CountryFactory(capital_city=paris) 1727 >>> City.objects.count() # No new capital_city generated 1728 1 1729 >>> guyane = CountryFactory(capital_city=paris, capital_city__name='Kourou') 1730 >>> City.objects.count() # No new capital_city generated, ``name`` ignored. 1731 1 1732 1733 1734.. note:: The target of the :class:`RelatedFactory` is evaluated *after* the initial factory has been instantiated. 1735 However, the build context is passed down to that factory; this means that calls to 1736 :class:`factory.SelfAttribute` *can* go back to the calling factory's context: 1737 1738 .. code-block:: python 1739 1740 class CountryFactory(factory.Factory): 1741 class Meta: 1742 model = Country 1743 1744 lang = 'fr' 1745 capital_city = factory.RelatedFactory( 1746 CityFactory, 1747 factory_related_name='capital_of', 1748 # Would also work with SelfAttribute('capital_of.lang') 1749 main_lang=factory.SelfAttribute('..lang'), 1750 ) 1751 1752RelatedFactoryList 1753"""""""""""""""""" 1754 1755.. class:: RelatedFactoryList(factory, factory_related_name='', size=2, **kwargs) 1756 1757 .. OHAI_VIM** 1758 1759 A :class:`RelatedFactoryList` behaves like a :class:`RelatedFactory`, only it returns a 1760 list of factories. This is useful for simulating one-to-many relations, rather than the 1761 one-to-one relation generated by :class:`RelatedFactory`. 1762 1763 1764 .. attribute:: factory 1765 1766 As for :class:`SubFactory`, the :attr:`factory` argument can be: 1767 1768 - A :class:`Factory` subclass 1769 - Or the fully qualified path to a :class:`Factory` subclass 1770 (see :ref:`subfactory-circular` for details) 1771 1772 .. attribute:: factory_related_name 1773 1774 If set, the object generated by the factory declaring the 1775 ``RelatedFactory`` is passed as keyword argument to the related factory. 1776 1777 .. attribute:: size 1778 1779 Either an ``int``, or a ``lambda`` that returns an ``int``, which will define the number 1780 of related Factories to be generated for each parent object. 1781 1782 .. versionadded:: 2.12 1783 1784 Note that the API for :class:`RelatedFactoryList` is considered experimental, and might change 1785 in a future version for increased consistency with other declarations. 1786 1787.. note:: 1788 Note that using a ``lambda`` for :attr:`size` allows the number of related objects per 1789 parents object to vary. This is useful for testing, when you likely don't want your mock 1790 data to have parent objects with the exact same, static number of related objects. 1791 1792 .. code-block:: python 1793 1794 class FooFactory(factory.Factory): 1795 class Meta: 1796 model = Foo 1797 # Generate a list of `factory` objects of random size, ranging from 1 -> 5 1798 bar = factory.RelatedFactoryList(BarFactory, size=lambda: random.randint(1, 5)) 1799 # Each Foo object will have exactly 3 Bar objects generated for its foobar attribute. 1800 foobar = factory.RelatedFactoryList(BarFactory, size=3) 1801 1802 1803PostGeneration 1804"""""""""""""" 1805 1806.. class:: PostGeneration(callable) 1807 1808The :class:`PostGeneration` declaration performs actions once the model object 1809has been generated. 1810 1811Its sole argument is a callable, that will be called once the base object has 1812been generated. 1813 1814Once the base object has been generated, the provided callable will be called 1815as ``callable(obj, create, extracted, **kwargs)``, where: 1816 1817- ``obj`` is the base object previously generated 1818- ``create`` is a boolean indicating which strategy was used 1819- ``extracted`` is ``None`` unless a value was passed in for the 1820 :class:`PostGeneration` declaration at :class:`Factory` declaration time 1821- ``kwargs`` are any extra parameters passed as ``attr__key=value`` when calling 1822 the :class:`Factory`: 1823 1824 1825.. code-block:: python 1826 1827 class UserFactory(factory.Factory): 1828 class Meta: 1829 model = User 1830 1831 login = 'john' 1832 make_mbox = factory.PostGeneration( 1833 lambda obj, create, extracted, **kwargs: os.makedirs(obj.login)) 1834 1835.. OHAI_VIM** 1836 1837Decorator 1838~~~~~~~~~ 1839 1840.. function:: post_generation 1841 1842A decorator is also provided, decorating a single method accepting the same 1843``obj``, ``create``, ``extracted`` and keyword arguments as :class:`PostGeneration`. 1844 1845 1846.. code-block:: python 1847 1848 class UserFactory(factory.Factory): 1849 class Meta: 1850 model = User 1851 1852 login = 'john' 1853 1854 @factory.post_generation 1855 def mbox(obj, create, extracted, **kwargs): 1856 if not create: 1857 return 1858 path = extracted or os.path.join('/tmp/mbox/', obj.login) 1859 os.path.makedirs(path) 1860 return path 1861 1862.. OHAI_VIM** 1863 1864.. code-block:: pycon 1865 1866 >>> UserFactory.build() # Nothing was created 1867 >>> UserFactory.create() # Creates dir /tmp/mbox/john 1868 >>> UserFactory.create(login='jack') # Creates dir /tmp/mbox/jack 1869 >>> UserFactory.create(mbox='/tmp/alt') # Creates dir /tmp/alt 1870 1871 1872PostGenerationMethodCall 1873"""""""""""""""""""""""" 1874 1875.. class:: PostGenerationMethodCall(method_name, *arg, **kwargs) 1876 1877 .. OHAI_VIM* 1878 1879 The :class:`PostGenerationMethodCall` declaration will call a method on 1880 the generated object just after instantiation. This declaration class 1881 provides a friendly means of generating attributes of a factory instance 1882 during initialization. The declaration is created using the following arguments: 1883 1884 .. attribute:: method_name 1885 1886 The name of the method to call on the :attr:`~FactoryOptions.model` object 1887 1888 .. attribute:: arg 1889 1890 The default, optional, positional argument to pass to the method given in 1891 :attr:`method_name` 1892 1893 .. attribute:: kwargs 1894 1895 The default set of keyword arguments to pass to the method given in 1896 :attr:`method_name` 1897 1898Once the factory instance has been generated, the method specified in 1899:attr:`~PostGenerationMethodCall.method_name` will be called on the generated object 1900with any arguments specified in the :class:`PostGenerationMethodCall` declaration, by 1901default. 1902 1903For example, we could use ``PostGenerationMethodCall`` to register created 1904users in an external system. 1905 1906.. code-block:: python 1907 1908 class User(models.Model): 1909 name = models.CharField(max_length=191) 1910 1911 def register(self, system, auth_token="ABC"): 1912 self.registration_id = system.register(auth_token) 1913 1914 1915 class UserFactory(factory.DjangoModelFactory): 1916 class Meta: 1917 model = User 1918 1919 name = 'user' 1920 register = factory.PostGenerationMethodCall("register", DefaultRegistry()) 1921 1922If the :class:`PostGenerationMethodCall` declaration contained no 1923arguments or one argument, an overriding value can be passed 1924directly to the method through a keyword argument matching the attribute name. 1925 1926.. code-block:: pycon 1927 1928 >>> # DefaultRegistry uses UUID for identifiers. 1929 >>> UserFactory().registration_id 1930 'edf42c11-0065-43ad-ad3d-78ab7497aaae' 1931 >>> # OtherRegistry uses int for identifiers. 1932 >>> UserFactory(register=OtherRegistry()).registration_id 1933 123456 1934 1935.. warning:: In order to keep a consistent and simple API, a :class:`PostGenerationMethodCall` 1936 allows *at most one* positional argument; all other parameters should be passed as 1937 keyword arguments. 1938 1939Keywords extracted from the factory arguments are merged into the 1940defaults present in the :class:`PostGenerationMethodCall` declaration. 1941 1942.. code-block:: pycon 1943 1944 >>> # Calls user.register(DefaultRegistry(), auth_token="DEF") 1945 >>> UserFactory(register__auth_token="DEF") 1946 1947Module-level functions 1948---------------------- 1949 1950Beyond the :class:`Factory` class and the various :ref:`declarations` classes 1951and methods, factory_boy exposes a few module-level functions, mostly useful 1952for lightweight factory generation. 1953 1954 1955Lightweight factory declaration 1956""""""""""""""""""""""""""""""" 1957 1958.. function:: make_factory(klass, **kwargs) 1959 1960 .. OHAI_VIM** 1961 1962 The :func:`make_factory` function takes a class, declarations as keyword arguments, 1963 and generates a new :class:`Factory` for that class accordingly: 1964 1965 .. code-block:: python 1966 1967 UserFactory = make_factory(User, 1968 login='john', 1969 email=factory.LazyAttribute(lambda u: '%s@example.com' % u.login), 1970 ) 1971 1972 # This is equivalent to: 1973 1974 class UserFactory(factory.Factory): 1975 class Meta: 1976 model = User 1977 1978 login = 'john' 1979 email = factory.LazyAttribute(lambda u: '%s@example.com' % u.login) 1980 1981 An alternate base class to :class:`Factory` can be specified in the 1982 ``FACTORY_CLASS`` argument: 1983 1984 .. code-block:: python 1985 1986 UserFactory = make_factory(models.User, 1987 login='john', 1988 email=factory.LazyAttribute(lambda u: '%s@example.com' % u.login), 1989 FACTORY_CLASS=factory.django.DjangoModelFactory, 1990 ) 1991 1992 # This is equivalent to: 1993 1994 class UserFactory(factory.django.DjangoModelFactory): 1995 class Meta: 1996 model = models.User 1997 1998 login = 'john' 1999 email = factory.LazyAttribute(lambda u: '%s@example.com' % u.login) 2000 2001 .. versionadded:: 2.0.0 2002 The ``FACTORY_CLASS`` kwarg was added in 2.0.0. 2003 2004 2005Instance building 2006""""""""""""""""" 2007 2008The :mod:`factory` module provides a bunch of shortcuts for creating a factory and 2009extracting instances from them. Helper methods can be used to create factories 2010in a dynamic way based on parameters. 2011 2012Internally, helper methods use :func:`make_factory` to create a new 2013:class:`Factory` and perform additional calls on the newly created 2014:class:`Factory` according to the method name. 2015 2016Please note, that all Factories created with this methods inherit from the 2017:class:`factory.base.Factory` class. For full support of your ``ORM``, specify 2018a base class with the ``FACTORY_CLASS`` parameter as shown in 2019:func:`make_factory` examples. 2020 2021.. function:: build(klass, FACTORY_CLASS=None, **kwargs) 2022.. function:: build_batch(klass, size, FACTORY_CLASS=None, **kwargs) 2023 2024 Create a factory for :obj:`klass` using declarations passed in kwargs; 2025 return an instance built from that factory with :data:`BUILD_STRATEGY`, 2026 or a list of :obj:`size` instances (for :func:`build_batch`). 2027 2028 :param class klass: Class of the instance to build 2029 :param int size: Number of instances to build 2030 :param kwargs: Declarations to use for the generated factory 2031 :param FACTORY_CLASS: Alternate base class (instead of :class:`Factory`) 2032 2033 2034 2035.. function:: create(klass, FACTORY_CLASS=None, **kwargs) 2036.. function:: create_batch(klass, size, FACTORY_CLASS=None, **kwargs) 2037 2038 Create a factory for :obj:`klass` using declarations passed in kwargs; 2039 return an instance created from that factory with :data:`CREATE_STRATEGY`, 2040 or a list of :obj:`size` instances (for :func:`create_batch`). 2041 2042 :param class klass: Class of the instance to create 2043 :param int size: Number of instances to create 2044 :param kwargs: Declarations to use for the generated factory 2045 :param FACTORY_CLASS: Alternate base class (instead of :class:`Factory`) 2046 2047 2048 2049.. function:: stub(klass, FACTORY_CLASS=None, **kwargs) 2050.. function:: stub_batch(klass, size, FACTORY_CLASS=None, **kwargs) 2051 2052 Create a factory for :obj:`klass` using declarations passed in kwargs; 2053 return an instance stubbed from that factory with :data:`STUB_STRATEGY`, 2054 or a list of :obj:`size` instances (for :func:`stub_batch`). 2055 2056 :param class klass: Class of the instance to stub 2057 :param int size: Number of instances to stub 2058 :param kwargs: Declarations to use for the generated factory 2059 :param FACTORY_CLASS: Alternate base class (instead of :class:`Factory`) 2060 2061 2062 2063.. function:: generate(klass, strategy, FACTORY_CLASS=None, **kwargs) 2064.. function:: generate_batch(klass, strategy, size, FACTORY_CLASS=None, **kwargs) 2065 2066 Create a factory for :obj:`klass` using declarations passed in kwargs; 2067 return an instance generated from that factory with the :obj:`strategy` strategy, 2068 or a list of :obj:`size` instances (for :func:`generate_batch`). 2069 2070 :param class klass: Class of the instance to generate 2071 :param str strategy: The strategy to use 2072 :param int size: Number of instances to generate 2073 :param kwargs: Declarations to use for the generated factory 2074 :param FACTORY_CLASS: Alternate base class (instead of :class:`Factory`) 2075 2076 2077 2078.. function:: simple_generate(klass, create, FACTORY_CLASS=None, **kwargs) 2079.. function:: simple_generate_batch(klass, create, size, FACTORY_CLASS=None, **kwargs) 2080 2081 Create a factory for :obj:`klass` using declarations passed in kwargs; 2082 return an instance generated from that factory according to the :obj:`create` flag, 2083 or a list of :obj:`size` instances (for :func:`simple_generate_batch`). 2084 2085 :param class klass: Class of the instance to generate 2086 :param bool create: Whether to build (``False``) or create (``True``) instances 2087 :param int size: Number of instances to generate 2088 :param kwargs: Declarations to use for the generated factory 2089 :param FACTORY_CLASS: Alternate base class (instead of :class:`Factory`) 2090 2091 2092Randomness management 2093--------------------- 2094 2095.. currentmodule:: factory.random 2096 2097Using :mod:`random` in factories allows to "fuzz" a program efficiently. 2098However, it's sometimes required to *reproduce* a failing test. 2099 2100:mod:`factory.fuzzy` and :class:`factory.Faker` share a dedicated instance 2101of :class:`random.Random`, which can be managed through the :mod:`factory.random` module: 2102 2103.. method:: get_random_state() 2104 2105 Call :meth:`get_random_state` to retrieve the random generator's current 2106 state. This method synchronizes both Faker’s and factory_boy’s random state. 2107 The returned object is implementation-specific. 2108 2109.. method:: set_random_state(state) 2110 2111 Use :meth:`set_random_state` to set a custom state into the random generator 2112 (fetched from :meth:`get_random_state` in a previous run, for instance) 2113 2114.. method:: reseed_random(seed) 2115 2116 The :meth:`reseed_random` function allows to load a chosen seed into the random generator. 2117 That seed can be anything accepted by :meth:`random.seed`. 2118 2119See :ref:`recipe-random-management` for help in using those methods in a test setup. 2120