【问题标题】:Factory boy in django for non-database fieldsdjango 中非数据库字段的工厂男孩
【发布时间】:2014-09-16 02:18:56
【问题描述】:

我有一个 django 模型,它在保存时会触发在外部服务上创建帐户(与 django 没有任何关系)。不过,为了测试,我想禁止创建此帐户。我可以覆盖管理器的 save() 方法并从那里弹出 kwarg,或者我可以按照Non-database field in Django model 向模型添加一个非数据库字段属性并在我的保存方法中检查它。

但是,当我尝试使用 factoryboy 创建对象时,它似乎会检查模型中的真实字段,由于属性不是字段而导致崩溃。

class MyModel(models.Model):
    name = models.CharField()
    create_external_account = True
    def save(self, *args, **kwargs):
        if create_external_account:
            ...

class MyModelFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = MyModel
    name = factory.Sequence(lambda n: 'name%d' % n)
    create_external_account = False

关于如何通过 factoryboy 传递诸如此类的额外参数有什么想法吗?

【问题讨论】:

    标签: django testing factory-boy


    【解决方案1】:

    你可以customize_create方法。

    如果外部帐户是在信号处理程序中创建的,您也可以disable signals

    【讨论】:

    • 在正确的轨道上,但是 AFAICT 这不会让我根据具体情况设置或取消设置标志;必须为整个工厂设置(或取消设置)。在某些测试中,我需要设置此标志,因为我想检查是否创建了外部帐户。我想我可以创建两个不同的工厂,一个设置它,一个不设置。
    【解决方案2】:

    factory_boycreate() 调用模型的 MyModel.objects.create(**kwargs) 方法。

    当你写 MyModelFactory() 时,它会调用:

    obj = MyModel(name="name01", create_external_account=False)
    obj.save()
    return obj
    

    在这里,您应该重写模型的 __init__ 方法来处理您的自定义字段:

    class MyModel(django.db.models.Model):
        def __init__(self, *args, **kwargs):
            self.create_external_account = kwargs.pop('create_external_account', False)
            return super(MyModel, self).__init__(*args, **kwargs)
    

    【讨论】:

      【解决方案3】:

      【讨论】:

      • 非常感谢!我没有在文档中注意到这一点,它为我节省了很多工作。
      猜你喜欢
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-29
      相关资源
      最近更新 更多