File: test_save_fields.py

package info (click to toggle)
django-dirtyfields 1.3.1-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 276 kB
  • sloc: python: 812; makefile: 168
file content (128 lines) | stat: -rw-r--r-- 4,430 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import django
import pytest

from .models import TestModel, TestMixedFieldsModel, TestModelWithForeignKey
from .utils import assert_number_of_queries_on_regex


@pytest.mark.django_db
def test_save_dirty_simple_field():
    tm = TestModel.objects.create()

    tm.characters = 'new_character'

    with assert_number_of_queries_on_regex(r'.*characters.*', 1):
        with assert_number_of_queries_on_regex(r'.*boolean.*', 1):
            tm.save()

    tm.characters = 'new_character_2'

    # Naive checking on fields involved in Django query
    # boolean unchanged field is not updated on Django update query: GOOD !
    with assert_number_of_queries_on_regex(r'.*characters.*', 1):
        with assert_number_of_queries_on_regex(r'.*boolean.*', 0):
            tm.save_dirty_fields()

    # We also check that the value has been correctly updated by our custom function
    assert tm.get_dirty_fields() == {}
    assert TestModel.objects.get(pk=tm.pk).characters == 'new_character_2'


@pytest.mark.django_db
def test_save_dirty_related_field():
    tm1 = TestModel.objects.create()
    tm2 = TestModel.objects.create()
    tmfm = TestMixedFieldsModel.objects.create(fkey=tm1)

    tmfm.fkey = tm2

    with assert_number_of_queries_on_regex(r'.*fkey_id.*', 1):
        with assert_number_of_queries_on_regex(r'.*characters.*', 1):
            tmfm.save()

    tmfm.fkey = tm1

    # Naive checking on fields involved in Django query
    # characters unchanged field is not updated on Django update query: GOOD !
    with assert_number_of_queries_on_regex(r'.*fkey_id.*', 1):
        with assert_number_of_queries_on_regex(r'.*characters.*', 0):
            tmfm.save_dirty_fields()

    # We also check that the value has been correctly updated by our custom function
    assert tmfm.get_dirty_fields() == {}
    assert TestMixedFieldsModel.objects.get(pk=tmfm.pk).fkey_id == tm1.id


@pytest.mark.django_db
def test_save_only_specific_fields_should_let_other_fields_dirty():
    tm = TestModel.objects.create(boolean=True, characters='dummy')

    tm.boolean = False
    tm.characters = 'new_dummy'

    tm.save(update_fields=['boolean'])

    # 'characters' field should still be dirty, update_fields was only saving the 'boolean' field in the db
    assert tm.get_dirty_fields() == {'characters': 'dummy'}


@pytest.mark.django_db
def test_handle_foreignkeys_id_field_in_update_fields():
    tm1 = TestModel.objects.create(boolean=True, characters='dummy')
    tm2 = TestModel.objects.create(boolean=True, characters='dummy')
    tmwfk = TestModelWithForeignKey.objects.create(fkey=tm1)

    tmwfk.fkey = tm2
    assert tmwfk.get_dirty_fields(check_relationship=True) == {'fkey': tm1.pk}

    tmwfk.save(update_fields=['fkey_id'])
    assert tmwfk.get_dirty_fields(check_relationship=True) == {}


@pytest.mark.django_db
def test_correctly_handle_foreignkeys_id_field_in_update_fields():
    tm1 = TestModel.objects.create(boolean=True, characters='dummy')
    tm2 = TestModel.objects.create(boolean=True, characters='dummy')
    tmwfk = TestModelWithForeignKey.objects.create(fkey=tm1)

    tmwfk.fkey_id = tm2.pk
    assert tmwfk.get_dirty_fields(check_relationship=True) == {'fkey': tm1.pk}

    tmwfk.save(update_fields=['fkey'])
    assert tmwfk.get_dirty_fields(check_relationship=True) == {}


@pytest.mark.django_db
def test_save_deferred_field_with_update_fields():
    TestModel.objects.create()

    tm = TestModel.objects.defer('boolean').first()
    tm.boolean = False
    # Test that providing a deferred field to the update_fields
    # save parameter doesn't raise a KeyError anymore.
    tm.save(update_fields=['boolean'])


@pytest.mark.django_db
def test_deferred_field_was_not_dirty():
    TestModel.objects.create()
    tm = TestModel.objects.defer('boolean').first()
    tm.boolean = False
    assert tm.get_dirty_fields() == {}


@pytest.mark.django_db
def test_save_deferred_field_with_update_fields_behaviour():
    """ Behaviour of deferred fields has changed in Django 1.10.
    Once explicitly updated (using the save update_fields parameter),
    a field cannot be considered deferred anymore.
    """

    TestModel.objects.create()
    tm = TestModel.objects.defer('boolean').first()
    tm.save(update_fields=['boolean'])
    tm.boolean = False
    if django.VERSION < (1, 10):
        assert tm.get_dirty_fields() == {}
    else:
        assert tm.get_dirty_fields() == {'boolean': True}