Reputation: 1412
I am sharing my solution to my own problem to which I realised the solution while typing the question... it may be useful to others.
In my Django models I have a Gateway
that has a set of Node
s with and they both should have the same Vendor
.
class Vendor(models.Model):
name = models.CharField(max_length=80, null=False)
class Gateway(models.Model):
vendor = models.ForeignKey(Vendor, related_name='gateways')
class Node(models.Model):
gateway = models.ForeignKey(Gateway, related_name='nodes')
vendor = models.ForeignKey(Vendor, related_name='nodes')
Now I would like to generate fake data with factory boy
. Here the VendorFactory
and NodeFactory
.
class VendorFactory(factory.django.DjangoModelFactory):
class Meta:
model = Vendor
name = 'test_vendor'
class NodeFactory(factory.django.DjangoModelFactory):
class Meta:
model = Node
# is created after this node instance
vendor = factory.SubFactory(VendorFactory)
That works fine when creating the node = NodeFactory()
.
The problem is with the GatewayFactory
. What I would like is that gateway = GatewayFactory()
creates a Gateway
that is referenced by a Node
instance and both the Gateway and the Node using the same Vendor
.
A tried a few things but failed. Here one shot:
class GatewayFactory(factory.django.DjangoModelFactory):
class Meta:
model = Gateway
node = factory.RelatedFactory(NodeFactory, 'gateway', vendor=factory.LazyAttribute(lambda o: o.vendor))
vendor = factory.SubFactory(VendorFactory)
The problem is that the RelatedFactory
is evaluated after the GatewayFactory and a LazyAttribute
or a SelfAttribute
are evaluated in the context of the NodeFactory.
Upvotes: 4
Views: 810
Reputation: 1412
The solution is in the fact that "the RelatedFactory is evaluated after the GatewayFactory and a LazyAttribute or a SelfAttribute are evaluated in the context of the NodeFactory"
Thus, we can reference the parent to get the vendor attribute:
class GatewayFactory(factory.django.DjangoModelFactory):
class Meta:
model = Gateway
node = factory.RelatedFactory(NodeFactory, 'gateway', vendor=factory.SelfAttribute('gateway.vendor'))
vendor = factory.SubFactory(VendorFactory)
This works for the LazyAttribute
as well:
class GatewayFactory(factory.django.DjangoModelFactory):
class Meta:
model = Gateway
node = factory.RelatedFactory(NodeFactory, 'gateway', vendor=factory.LazyAttribute(lambda o: o.gateway.vendor))
vendor = factory.SubFactory(VendorFactory)
Upvotes: 2