#python #django #faker #factory-boy
#python #django #мошенник #factory-boy
Вопрос:
Используя Factory Boy и Faker в проекте Django, я хотел бы создать выведенные атрибуты, то есть метод from Faker
возвращает набор значений, которые зависят друг от друга. Эти значения будут использоваться для других атрибутов класса Factory.
Пример: location_on_land
метод from faker.providers.geo
возвращает кортеж из широты, долготы, названия места, двухбуквенного кода страны и часового пояса (например (‘38.70734’, ‘-77.02303’, ‘ Форт Вашингтон», «США», «Америка /Нью-Йорк»). Все значения зависят друг от друга, поскольку координаты определяют место, страну, часовой пояс и т. Д. Поэтому я не могу использовать отдельные функции для (ленивых) атрибутов, таких как faker.providers.latitude
, faker.providers.longitude
.
Возможно ли каким-либо образом получить доступ к возвращаемым значениям из атрибута lazy, чтобы использовать их для других выведенных атрибутов? Есть ли лучший способ получить доступ к возвращаемым значениям, location_on_land
чтобы использовать их для других зависимых атрибутов, мой фабричный класс выглядит следующим образом:
# 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",
...
)
Ответ №1:
При использовании factory.Params
результирующий атрибут доступен для первого параметра 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])
)
Комментарии:
1. Большое вам спасибо, у меня есть часы поиска, чтобы найти решение! Я довольно новичок в Factory Boy, поэтому я вообще не знал об этом
Params
классе.