Created
February 2, 2023 22:57
-
-
Save quevon24/e2a9d0a812927d3d444306e79b98009b to your computer and use it in GitHub Desktop.
Pass data on the fly to factory_boy factory using custom RelatedFactoryList class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import copy | |
from factory import RelatedFactoryList | |
class RelatedFactoryVariableList(RelatedFactoryList): | |
"""This factory allows you to specify how many related objects do you | |
want to create, but also allows you to define the data for each related | |
object. | |
Usage example: | |
# This will create 4 objects | |
FooFactory(bars__size=4) | |
# This will create 3 objects, with different data for each one | |
FooFactory(bars__data=[{"name": "a"}, {"name": "b"}, {"name": "c"}]) | |
# Based on answer here: https://github.com/FactoryBoy/factory_boy/issues/767 | |
""" | |
def call(self, instance, step, context): | |
size = context.extra.pop("size", None) | |
data = context.extra.pop("data", []) | |
if size and data: | |
if size != len(data): | |
raise TypeError( | |
"RelatedFactoryVariableList you can only use data or size, not both." | |
) | |
if not size and not data: | |
size = self.size | |
if size and not data: | |
# Generate size number of objects | |
return [ | |
super(RelatedFactoryList, self).call(instance, step, context) | |
for i in range(size) | |
] | |
results = [] | |
for d in data: | |
# Create copy of PostGenerationContext object | |
copied_context = copy.deepcopy(context) | |
if isinstance(d, dict): | |
# Update data for each factory instance | |
copied_context.extra.update(d) | |
results.append( | |
super(RelatedFactoryList, self).call( | |
instance, step, copied_context | |
) | |
) | |
return results |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment