question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

auto_now_add overrides factoryboy params

See original GitHub issue

Say I have a model:

class Foo(models.Model):
    foo = models.DateField(auto_now_add=True)

with a trivial factory FooFactory, if I then do:

print FooFactory(foo=date(2001, 1, 1)).foo

it prints the current date, not the one I specified. To me this is a violation of principle of least surprise.

Issue Analytics

  • State:closed
  • Created 10 years ago
  • Reactions:9
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

29reactions
rbarroiscommented, Nov 7, 2013

Hi,

That’s a built-in “feature” of Django: when a field has auto_now_add=True, Django will override any provided value with django.utils.timezone.now() ; this happens ‘‘after’’ factory_boy’s code runs.

You have two options:

  1. Override your factory’ _create function:
class FooFactory(factory.django.DjangoModelFactory):
    FACTORY_FOR = models.Foo

    @classmethod
    def _create(cls, target_class, *args, **kwargs)
        foo = kwargs.pop('foo', None)
        obj = super(FooFactory, cls)._create(target_class, *args, **kwargs)
        if foo is not None:
            obj.foo = foo
            obj.save()
        return obj
  1. Replace auto_now_add=True with the default keyword argument to models:
from django.utils import timezone

class Foo(models.Model):
    foo = models.DateField(default=timezone.now)

Note the lack of brackets in default=timezone.now; this could also be written as default=lambda: timezone.now() to be more explicit.

I have personnally chosen the second version, which lets me override created_at fields easily in tests.

0reactions
pymencommented, Dec 15, 2021

Here is my way to do it in a universal way with freeze gun https://stackoverflow.com/a/70364787/1731460

Read more comments on GitHub >

github_iconTop Results From Across the Web

Reference — Factory Boy stable documentation
The extra parameters attached to a Factory are declared through a Params class. ... A Factory subclass may override a couple of class...
Read more >
Temporarily disable auto_now / auto_now_add - Stack Overflow
I want to overwrite the two date fields for some model instances (used when migrating data). The current solution looks like this:
Read more >
Testing Models with Django using Faker and Factory Boy
The factory_boy library(modeled after Factory Girl in Rails) the generation of data for tests. ... Build a Company instance and override company
Read more >
Two Scoops of Django: Best Practices for Django 1.8
12.3 Pattern 3: Overriding the Clean Stage of Validation . ... auto now add. If so, you will ... parameter to ValidationError as...
Read more >
Two Scoops of Django: Best Practices for Django 1.8
12.3 Pattern 3: Overriding the Clean Stage of Validation . ... auto now add. If so, you will ... parameter to ValidationError as...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found