python - 工厂男孩 - 如何创建工厂所需的数据(预生成挂钩)
问题描述
注意:我将尝试用一个简化的场景来解释这个用例(这对你来说可能看起来很奇怪)。
我有 2 个模型(相关但没有外键):
# models.py
class User(models.Model):
name = models.CharField()
age = models.IntegerField()
weight = models.IntegerField()
# there are a lot more properties ...
class Group(models.Model):
name = models.CharField()
summary = JSONField()
def save(self, *args, **kwargs):
self.summary = _update_summary()
super().save(*args, **kwargs)
def _update_summary(self):
return calculate_group_summary(self.summary)
# this helper function is located in a helper file
def calculate_group_summary(group_summary):
"""calculates group.summary data based on group.users"""
# retrieve users, iterate over them, calculate data and store results in group_summary object
return group_summary
对于上述型号,我有这个工厂:
# factories.py
class UserFactory(factory.DjangoModelFactory):
class Meta:
model = User
name = factory.Sequence(lambda n: "user name %d" % n)
age = randint(10, 90))
weight = randint(30, 110))
class GroupFactory(factory.django.DjangoModelFactory):
class Meta:
model = Group
name = factory.Sequence(lambda n: "group name %d" % n)
summary = {
"users": [34, 66, 76],
"age": {
"mean": 0,
"max": 0,
"min": 0,
},
"weight": {
"mean": 0,
"max": 0,
"min": 0,
}
}
特殊性是我在 group.save() 上更新字段group.summary中的 JSON 数据。
注意:我不喜欢将其移至 post_save 信号,因为我想避免“双重”保存(我有创建/修订字段)。
所以当我使用 GroupFactory() 时,我必须让“用户”就位。
我正在查看后生成挂钩https://factoryboy.readthedocs.io/en/latest/reference.html#post-generation-hooks,但我需要“预生成挂钩”。
是否有在创建GroupFactory之前生成用户数据的“最佳实践” (无需在测试用例中手动创建它们)?类似于“后一代钩子”但“前”的东西?:|
解决方案
尝试使用_create()
钩子。像这样的东西:
class GroupFactory():
...
@classmethod
def _create(cls, model_class, *args, **kwargs):
# Create the prerequisite data here.
# Use `UserFactory.create_batch(n)` if multiple instances are needed.
user = UserFactory()
group = model_class(*args, **kwargs)
# Update other fields here if needed.
group.foo = bar
# Required operation.
group.save()
return group
参考:https ://factoryboy.readthedocs.io/en/latest/reference.html#factory.Factory._create
推荐阅读
- git - 有没有办法可以撤消不是最后一个的 git push
- ruby-on-rails - 每个子域的不同谷歌分析跟踪 ID
- laravel - 在laravel中将原始查询转换为雄辩的查询
- redirect - 如何将子目录更改为 Apache2 中的子域?
- qt - 将 QGLWidget 与 Qt5 一起使用时的性能问题
- html - 根据屏幕分辨率调整 iFrame 的高度
- javascript - Javascript全局变量未声明问题
- jquery - 在 Angular 项目中添加 jQuery DateTimePicker(非官方)后出现 jQuery 的参考错误
- c# - C# X509Certificate2.Verify 无撤销测试
- cmake - 安装 EXCLUDE_FROM_ALL 子目录