使用 Factory Boy 推导出 LazyAttribute 的属性
Deduced attributes of a LazyAttribute using Factory Boy
在 Django 项目中使用 Factory Boy and Faker,我想创建推导属性,这意味着来自 Faker
return 一组相互依赖的值的方法。这些值将用于工厂的其他属性 Class.
示例:
来自 faker.providers.geo
return 的 location_on_land
method 是纬度、经度、地名、两个字母的国家代码和时区的元组(例如('38.70734'、'-77.02303' , 'Fort Washington', 'US', 'America/New_York')。所有的值都相互依赖,因为坐标定义了地点、国家、时区等。因此我不能为 (lazy ) 属性,例如 faker.providers.latitude
、faker.providers.longitude
.
是否有可能以某种方式从惰性属性访问 return 值以将它们用于其他推导出的属性?有没有更好的方法从 location_on_land
访问 return 值以在其他依赖属性上使用它们
我的工厂-Class 看起来像这样:
# factory_models.py
class OriginFactory(factory.django.DjangoModelFactory):
"""Factory for Origin."""
class Meta:
model = models.Origin
exclude = [
"geo_data",
]
# not working since not a lazy attribute
# lat, lon, place, iso_3166_alpha_2, _ = fake.location_on_land()
# desired outcome (not working)
geo_data = factory.Faker("location_on_land")
# attributes using the return values of `location_on_land` from lazy attribute (pseudo-code, desired)
latitude = geo_data[...][0]
longitude = geo_data[...][1]
# foreign key
iso_3166_alpha_2 = models.Country.objects.get(iso_3166_alpha_2=geo_data[...][2])
...
# models.py
class Origin(models.Model):
origin_id = models.AutoField(
primary_key=True,
db_column="origin_id",
)
latitude = models.FloatField(
null=True,
db_column="latitude",
)
longitude = models.FloatField(
null=True,
db_column="longitude",
)
region = models.CharField(
max_length=100,
blank=True,
db_column="region",
)
iso_3166_alpha_2 = models.ForeignKey(
to=Country,
on_delete=models.PROTECT,
db_column="iso_3166_alpha_2",
...
)
使用factory.Params
, the resulting attribute is available on the first parameter on factory.LazyAttribute
时:传入的实例是一个存根,用于构建实际模型调用的参数。
对于你的情况,我会选择以下工厂。
请注意,geo_data
字段被声明为参数(即未传递给 models.Origin
构造函数);但它仍然可以用于工厂的其他声明。
class OriginFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.Origin
class Params:
geo_data = factory.Faker('location_on_land')
latitude = factory.LazyAttribute(lambda o: o.geo_data[0])
longitude = factory.LazyAttribute(lambda o: o.geo_data[1])
iso_3166_alpha_2 = factory.LazyAttribute(
lambda o: models.Country.objects.get(iso_3166_alpha_2=o.geo_data[3])
)
在 Django 项目中使用 Factory Boy and Faker,我想创建推导属性,这意味着来自 Faker
return 一组相互依赖的值的方法。这些值将用于工厂的其他属性 Class.
示例:
来自 faker.providers.geo
return 的 location_on_land
method 是纬度、经度、地名、两个字母的国家代码和时区的元组(例如('38.70734'、'-77.02303' , 'Fort Washington', 'US', 'America/New_York')。所有的值都相互依赖,因为坐标定义了地点、国家、时区等。因此我不能为 (lazy ) 属性,例如 faker.providers.latitude
、faker.providers.longitude
.
是否有可能以某种方式从惰性属性访问 return 值以将它们用于其他推导出的属性?有没有更好的方法从 location_on_land
访问 return 值以在其他依赖属性上使用它们
我的工厂-Class 看起来像这样:
# factory_models.py
class OriginFactory(factory.django.DjangoModelFactory):
"""Factory for Origin."""
class Meta:
model = models.Origin
exclude = [
"geo_data",
]
# not working since not a lazy attribute
# lat, lon, place, iso_3166_alpha_2, _ = fake.location_on_land()
# desired outcome (not working)
geo_data = factory.Faker("location_on_land")
# attributes using the return values of `location_on_land` from lazy attribute (pseudo-code, desired)
latitude = geo_data[...][0]
longitude = geo_data[...][1]
# foreign key
iso_3166_alpha_2 = models.Country.objects.get(iso_3166_alpha_2=geo_data[...][2])
...
# models.py
class Origin(models.Model):
origin_id = models.AutoField(
primary_key=True,
db_column="origin_id",
)
latitude = models.FloatField(
null=True,
db_column="latitude",
)
longitude = models.FloatField(
null=True,
db_column="longitude",
)
region = models.CharField(
max_length=100,
blank=True,
db_column="region",
)
iso_3166_alpha_2 = models.ForeignKey(
to=Country,
on_delete=models.PROTECT,
db_column="iso_3166_alpha_2",
...
)
使用factory.Params
, the resulting attribute is available on the first parameter on factory.LazyAttribute
时:传入的实例是一个存根,用于构建实际模型调用的参数。
对于你的情况,我会选择以下工厂。
请注意,geo_data
字段被声明为参数(即未传递给 models.Origin
构造函数);但它仍然可以用于工厂的其他声明。
class OriginFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.Origin
class Params:
geo_data = factory.Faker('location_on_land')
latitude = factory.LazyAttribute(lambda o: o.geo_data[0])
longitude = factory.LazyAttribute(lambda o: o.geo_data[1])
iso_3166_alpha_2 = factory.LazyAttribute(
lambda o: models.Country.objects.get(iso_3166_alpha_2=o.geo_data[3])
)