Skip to content
Back to top
View this page

# Testing with Django

Note

To ensure you are using compatible versions, install with the `testfixtures[django]` extra.

Django’s ORM has an unfortunate implementation choice of considering `Model` instances to be identical as long as their primary keys are the same:

    >>> from tests.test_django.models import SampleModel
    >>> SampleModel(id=1, value=1) == SampleModel(id=1, value=2)
    True

To work around this, `testfixtures.django` registers a `comparer` for the django `Model` class. However, for this to work, `ignore_eq=True` must be passed:

    >>> from testfixtures import compare
    >>> import testfixtures.django # to register the comparer...
    >>> compare(SampleModel(id=1, value=1), SampleModel(id=1, value=2),
    ...         ignore_eq=True)
    Traceback (most recent call last):
     ...
    AssertionError: SampleModel not as expected:

    same:
    ['id']

    values differ:
    'value': 1 != 2

Since the above can quickly become cumbersome, a django-specific version of `compare()` that ignores `__eq__` by default is provided:

    >>> from testfixtures.django import compare as django_compare
    >>> django_compare(SampleModel(id=1, value=1), SampleModel(id=1, value=2))
    Traceback (most recent call last):
     ...
    AssertionError: SampleModel not as expected:

    same:
    ['id']

    values differ:
    'value': 1 != 2

## Ignoring fields

It may also be that you want to ignore fields over which you have no control and cannot easily mock, such as created or modified times. For this, you can use the ignore_fields option:

    >>> compare(SampleModel(id=1, value=1), SampleModel(id=1, value=2),
    ...         ignore_eq=True, ignore_fields=['value'])

## Comparing non-editable fields

By default, non-editable fields are ignored:

    >>> django_compare(SampleModel(not_editable=1), SampleModel(not_editable=2))

If you wish to include these fields in the comparison, pass the `non_editable_fields` option:

    >>> django_compare(SampleModel(not_editable=1), SampleModel(not_editable=2),
    ...                non_editable_fields=True)
    Traceback (most recent call last):
     ...
    AssertionError: SampleModel not as expected:

    same:
    ['created', 'id', 'value']

    values differ:
    'not_editable': 1 != 2

Note

The registered comparer currently ignores `many to many` fields. Patches to fix this deficiency are welcome!