1

I am using Token Authentication in my Django Rest Framework project. I have noticed that while creating a token, if I specify the created datetime field in the create method, than the token is not created with that value, for example:

new_token = Token.objects.create(user=user, created=datetime(2021, 9, 7, 10, 10, 10, tzinfo=timezone.utc)

will not create the token with the specified datetime but will use the current UTC time. To make it work i have to perform another operation on this object and save the modified object again like this:

new_token = Token.objects.create(user=user) 
new_token.created = datetime(2021, 9, 7, 10, 10, 10, tzinfo=timezone.utc)
new_token.save()

I think this will make two queries on the DB, first while creating and then while modifying the created datetime which is not very elegant. Can someone please tell me why Django is not setting the datetime in the first way? I'm very new to this framework so please pardon me if I'm overlooking something very simple here.

Thanks!

Marry35
  • 387
  • 4
  • 16
  • may I ask why not use the `default=timezone.now` parameter on the `created` field on your `Token` object? Then you don't need to go through all this to begin with – David Culbreth Sep 12 '21 at 00:27
  • 1
    for the `DateTimeField`, you can also use the `auto_now_add` parameter like this: `created_date = models.DateTimeField(auto_now_add=True)` – David Culbreth Sep 12 '21 at 00:29
  • @DavidCulbreth thanks for your input. Actually, I have modified the behavior of Token Authentication a bit and want to write unit tests for it. I need to mock the created datetime in my tests for some cases. I cannot find the source code where Token Authentication sets the created datetime which I can mock, hence, my only option was to set it on my own and then mock that datetime. Am I making sense? Or could you point me towards a better solution? – Marry35 Sep 12 '21 at 09:41

1 Answers1

1

Okay, I figured out why this is the behavior of Token. If you see the code of Token model, the created field is defined as follows:

created = models.DateTimeField(_("Created"), auto_now_add=True)

The auto_now_add=True value specifies that this field will automatically be set to the current UTC time.

Now, what I wanted to do was to mock this created datetime in my unit tests to simulate some cases. I found out that you can just mock the django.utils.timezone.now return value to simulate any created datetime like this:

def my_unit_test(self):
   with patch('django.utils.timezone.now') as fake_dt:
       fake_dt.return_value = datetime(2021, 9, 7, 10, 10, 10, tzinfo=timezone.utc)
       # token's created field will be set to the datetime above
       token = Token.objects.create(user=test_user)

Dharman
  • 30,962
  • 25
  • 85
  • 135
Marry35
  • 387
  • 4
  • 16