Skip to main content

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

PyPI Version Build status

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
  • 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-override-autonow-0.0.1.tar.gz (5.6 kB view details)

Uploaded Source

Built Distribution

django_override_autonow-0.0.1-py3-none-any.whl (6.0 kB view details)

Uploaded Python 3

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

Hashes for django-override-autonow-0.0.1.tar.gz
Algorithm Hash digest
SHA256 017c39a926851a9ae070cb9ade39be8e7ead88a834e284016b6014f0050629f7
MD5 633160d800dec7ac7e3063e334c0d293
BLAKE2b-256 b10ee02cd80245c7b69ea79adf2120d90a662c93d7b461e177ad79f69e6c7dc3

See more details on using hashes here.

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

Hashes for django_override_autonow-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 cd838fd3a27859721c22b4e034c1993a3bb5ee500403499be4620c9223ac0108
MD5 a5e25c277aab050a20943cc89abf6d80
BLAKE2b-256 08f629ee4148c46c98352ef98d74207f9ab9ab5c9674252b196524233d8501b8

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page