Temporarily disable auto_now and auto_now_add option in Django's DateField and DateTimeField, so that you can save the desired value to these fields.
Project description
django-override-autonow is a testing tool for Django’s project. django-override-autonow makes it easy to create model instance using DateField or DateTimeField with auto_now or auto_now_add options.
An example of django’s model:
from django.db import models
class Order(models.Model):
amount = models.IntegerField()
status = models.CharField(max_length=100)
created_time = models.DateTimeField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True)
To test this model:
from unittest import mock
from django.test import TestCase
from django.utils import timezone
from override_autonow import override_autonow
from .models import Order
class TestOrder(TestCase):
@override_autonow
def test_with_django_override_autonow(self):
# We need a order with desired created_time and updated_time for test
order = Order.objects.create(
amount=200,
status='PAID',
created_time=timezone.datetime(year=2022, month=1, day=1, hour=23, minute=59, second=59),
updated_time=timezone.datetime(year=2022, month=1, day=2, hour=0, minute=0, second=0),
)
# test order
def test_without_django_override_autonow(self):
# Django's standard way is to mock timezone.now and save the model.
# First, create object with mocking timezone.now and set desired value to created_time field
with mock.patch('django.db.models.fields.timezone') as mock_timezone:
mock_timezone.now.return_value = timezone.datetime(year=2022, month=1, day=1, hour=23, minute=59, second=59)
order = Order.objects.create(
amount=200,
status='PAID',
)
# Second, save object again with mocking timezone.now and set desired value to updated_time field
with mock.patch('django.db.models.fields.timezone') as mock_timezone:
mock_timezone.now.return_value = timezone.datetime(year=2022, month=1, day=2, hour=0, minute=0, second=0)
order.save()
# test order
Features
Support Django 2.2+ and Python 3.7+
- Compatible with major testing packages
pytest’s class based test and function based test with pytest-django
factory-boy’s model factory
- Choose suitable style for your situation
Method decorator
Class decorator
Context manager
- Flexible override target selection
Affects only specified field names and exclude specified field names
Affects only specified models and exclude specified field names
Affects only auto_now option or auto_now_add option
Affects only DateField or DateTimeField
Installation
Installing from PyPI:
pip install django-override-autonow
Use Cases
Test with Django’s TestCase:
from django.test import TestCase
from override_autonow import override_autonow
from .models import Order
class TestOrder(TestCase):
# as method decorator
@override_autonow
def test_with_method_decorator(self):
order = Order.objects.create(
amount=200,
status='PAID',
created_time=timezone.datetime(year=2022, month=1, day=1, hour=23, minute=59, second=59),
updated_time=timezone.datetime(year=2022, month=1, day=2, hour=0, minute=0, second=0),
)
# test order
def test_with_context_manager(self):
# as context manager
with override_autonow():
order_with_override = Order.objects.create(
amount=200,
status='PAID',
created_time=timezone.datetime(year=2022, month=1, day=1, hour=23, minute=59, second=59),
updated_time=timezone.datetime(year=2022, month=1, day=2, hour=0, minute=0, second=0),
)
order_without_override = Order.objects.create(
amount=200,
status='PAID',
)
# test order
# as class decorator
@override_autonow
class TestWithClassDecorator(TestCase):
def test_with_class_decorator(self):
order = Order.objects.create(
amount=200,
status='PAID',
created_time=timezone.datetime(year=2022, month=1, day=1, hour=23, minute=59, second=59),
updated_time=timezone.datetime(year=2022, month=1, day=2, hour=0, minute=0, second=0),
)
# test order
Test with pytest(pytest-django):
import pytest
from override_autonow import override_autonow
from .models import Order
@pytest.mark.django_db
class TestOrder:
# as method decorator
@override_autonow
def test_with_method_decorator(self):
order = Order.objects.create(
amount=200,
status='PAID',
created_time=timezone.datetime(year=2022, month=1, day=1, hour=23, minute=59, second=59),
updated_time=timezone.datetime(year=2022, month=1, day=2, hour=0, minute=0, second=0),
)
# test order
def test_with_context_manager(self):
# as context manager
with override_autonow():
order_without_autonow = Order.objects.create(
amount=200,
status='PAID',
created_time=timezone.datetime(year=2022, month=1, day=1, hour=23, minute=59, second=59),
updated_time=timezone.datetime(year=2022, month=1, day=2, hour=0, minute=0, second=0),
)
order_with_autonow = Order.objects.create(
amount=200,
status='PAID',
)
# test order
# as class decorator
@override_autonow
@pytest.mark.django_db
class TestWithClassDecorator:
def test_with_class_decorator(self):
order = Order.objects.create(
amount=200,
status='PAID',
created_time=timezone.datetime(year=2022, month=1, day=1, hour=23, minute=59, second=59),
updated_time=timezone.datetime(year=2022, month=1, day=2, hour=0, minute=0, second=0),
)
# test order
Override specific targets:
from django.test import TestCase
from override_autonow import override_autonow
from .models import Order
class TestOrder(TestCase):
@override_autonow(exclude_auto_now=True)
def test_exclude_auto_now_option(self):
# Override only auto_now_add option
...
@override_autonow(exclude_auto_now_add=True)
def test_exclude_auto_now_add_option(self):
# Override only auto_now option
...
@override_autonow(exclude_date_field=True)
def test_exclude_date_field(self):
# Override only DateTimeField
...
@override_autonow(exclude_datetime_field=True)
def test_exclude_datetime_field(self):
# Override only DateField
...
@override_autonow(exclude_field_names={'created_time'})
def test_exclude_field_names(self):
# Override except fields named created_time
...
@override_autonow(exclude_models=(Order,))
def test_exclude_models(self):
# Override except the Order model
...
@override_autonow(override_field_names={'created_time'})
def test_override_field_names(self):
# Override only fields named created_time
...
@override_autonow(override_models=(Order,))
def test_override_models(self):
# Override only the Order model
...
Test with factory-bot:
from django.test import TestCase
from django.utils import timezone
from factory.django import DjangoModelFactory
from override_autonow import override_autonow
from .models import Order
class OrderFactory:
class Meta:
model = Order
amount = 200,
status = 'PAID',
created_time = timezone.datetime(year=2022, month=1, day=1, hour=23, minute=59, second=59)
updated_time = timezone.datetime(year=2022, month=1, day=2, hour=0, minute=0, second=0)
class TestOrder(TestCase):
@override_autonow
def test_with_method_decorator(self):
# Override created_time and updated_time with factory
order = OrderFactory()
# test order
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file django-override-autonow-0.0.1.tar.gz
.
File metadata
- Download URL: django-override-autonow-0.0.1.tar.gz
- Upload date:
- Size: 5.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.7.12
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 017c39a926851a9ae070cb9ade39be8e7ead88a834e284016b6014f0050629f7 |
|
MD5 | 633160d800dec7ac7e3063e334c0d293 |
|
BLAKE2b-256 | b10ee02cd80245c7b69ea79adf2120d90a662c93d7b461e177ad79f69e6c7dc3 |
File details
Details for the file django_override_autonow-0.0.1-py3-none-any.whl
.
File metadata
- Download URL: django_override_autonow-0.0.1-py3-none-any.whl
- Upload date:
- Size: 6.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.7.12
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cd838fd3a27859721c22b4e034c1993a3bb5ee500403499be4620c9223ac0108 |
|
MD5 | a5e25c277aab050a20943cc89abf6d80 |
|
BLAKE2b-256 | 08f629ee4148c46c98352ef98d74207f9ab9ab5c9674252b196524233d8501b8 |