使用FactoryBoy自动添加

时间:2018-10-11 05:01:32

标签: django django-models factory-boy

此问题:https://github.com/FactoryBoy/factory_boy/issues/102 描述了如何在Django中测试“已创建”字段。

应如何为auto_add(而不是auto_add_now)实现此功能?我有一个“已更新”字段,但是是否使用

models.DateTimeField(auto_now=True) 

或覆盖Django模型.save()方法

def save(self, *args, **kwargs):
    """On save, update updated timestamp"""
    self.updated = timezone.now
    return super(Task, self).save(*args, **kwargs)

我似乎无法让FactoryBoy返回我想要的更新值-它总是返回timezone.now()

LazyAttribute(lambda o: o.created + timedelta(hours=1))   # ignored by auto_add

或使用GitHub问题中建议的_create()方法:

@classmethod
def _create(cls, target_class, *args, **kwargs)
    updated = kwargs.pop('updated', None)
    obj = super(TaskFactory, cls)._create(target_class, *args, **kwargs)
    if updated is not None:
        obj.updated = updated
        obj.save()   # <-- calls .save() method overriding with timezone.now()
    return obj

去这里最好的方法是什么?

2 个答案:

答案 0 :(得分:0)

到目前为止,对于其他为此苦苦挣扎的人,我发现的唯一方法是在传递给Factory boy之前对原始模型上的.save()方法进行猴子补丁:

models.py:

updated = models.DateTimeField(default=timezone.now)
def save(self, *args, **kwargs):
    """On save, update updated timestamp"""
    self.updated = timezone.now
    return super(Task, self).save(*args, **kwargs)

factories.py:

updated = LazyAttribute(lambda o: o.created + timedelta(hours=1))

def patched_save(self, *args, **kwargs):
    return super(Task, self).save(*args, **kwargs)

Task.save = patched_save

但希望能听到其他(可能更好)的建议!

答案 1 :(得分:0)

只需将这样的内容添加到任务工厂:

from django.db import models

@classmethod
def _create(cls, target_class, *args, **kwargs):
    updated = kwargs.pop('updated', None)
    task = super()._create(target_class, *args, **kwargs)

    if updated is not None:
        task.updated = updated
        models.Model.save(task)  # This does the magic

    return task

注意:我们称models.Model.save(task),而不是task.save()