【问题标题】:auto_add with FactoryBoy使用 FactoryBoy 自动添加
【发布时间】:2018-10-11 05:01:32
【问题描述】:

本期: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

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

【问题讨论】:

    标签: django django-models factory-boy


    【解决方案1】:

    对于其他为此苦苦挣扎的人,到目前为止,我发现的唯一方法是在传递给 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
    

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

    【讨论】:

      【解决方案2】:

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

      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()

      【讨论】:

        猜你喜欢
        • 2018-01-24
        • 1970-01-01
        • 2012-11-14
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 2011-09-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多