Skip to content

Commit cc458f1

Browse files
committed
[models] Replaced thirdparty JSONField with Django built-in JSONField #1061
Replaced jsonfield package's JSONField with Django's built-in JSONField across all models to use the modern, maintained Django implementation. Closes #1061
1 parent 012a094 commit cc458f1

27 files changed

+397
-151
lines changed

openwisp_controller/config/admin.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
ObjectDoesNotExist,
1616
ValidationError,
1717
)
18+
from django.db import models
1819
from django.http import Http404, HttpResponse, HttpResponseRedirect, JsonResponse
1920
from django.http.response import HttpResponseForbidden
2021
from django.shortcuts import get_object_or_404
@@ -215,6 +216,12 @@ def _get_preview_instance(self, request):
215216
key = "{relation}_id".format(relation=key)
216217
# pass non-empty string or None
217218
kwargs[key] = value or None
219+
# parse JSON strings for JSONField fields
220+
elif isinstance(field, models.JSONField) and isinstance(value, str):
221+
try:
222+
kwargs[key] = json.loads(value) if value else None
223+
except json.JSONDecodeError:
224+
kwargs[key] = value
218225
# put regular field values in kwargs dict
219226
else:
220227
kwargs[key] = value

openwisp_controller/config/base/base.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
import collections
21
import hashlib
32
import json
43
import logging
54
from copy import deepcopy
65

76
from cache_memoize import cache_memoize
87
from django.core.exceptions import ValidationError
8+
from django.core.serializers.json import DjangoJSONEncoder
99
from django.db import models
10+
from django.db.models import JSONField
1011
from django.utils.functional import cached_property
1112
from django.utils.module_loading import import_string
1213
from django.utils.translation import gettext_lazy as _
13-
from jsonfield import JSONField
1414
from netjsonconfig.exceptions import ValidationError as SchemaError
1515

1616
from openwisp_utils.base import TimeStampedEditableModel
@@ -126,8 +126,7 @@ class BaseConfig(BaseModel):
126126
_("configuration"),
127127
default=dict,
128128
help_text=_("configuration in NetJSON DeviceConfiguration format"),
129-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
130-
dump_kwargs={"indent": 4},
129+
encoder=DjangoJSONEncoder,
131130
)
132131

133132
__template__ = False

openwisp_controller/config/base/config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
from cache_memoize import cache_memoize
77
from django.core.cache import cache
88
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied, ValidationError
9+
from django.core.serializers.json import DjangoJSONEncoder
910
from django.db import models, transaction
11+
from django.db.models import JSONField
1012
from django.utils.translation import gettext_lazy as _
11-
from jsonfield import JSONField
1213
from model_utils import Choices
1314
from model_utils.fields import StatusField
1415
from netjsonconfig import OpenWrt
@@ -90,8 +91,7 @@ class AbstractConfig(ChecksumCacheMixin, BaseConfig):
9091
'en/stable/general/basics.html#context" target="_blank">'
9192
"context (configuration variables)</a> in JSON format"
9293
),
93-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
94-
dump_kwargs={"indent": 4},
94+
encoder=DjangoJSONEncoder,
9595
)
9696
checksum_db = models.CharField(
9797
_("configuration checksum"),

openwisp_controller/config/base/device_group.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import collections
21
from copy import deepcopy
32

43
import jsonschema
54
from django.core.exceptions import ValidationError
5+
from django.core.serializers.json import DjangoJSONEncoder
66
from django.db import models
7+
from django.db.models import JSONField
78
from django.utils.translation import gettext_lazy as _
8-
from jsonfield import JSONField
99
from jsonschema.exceptions import ValidationError as SchemaError
1010
from swapper import get_model_name, load_model
1111

@@ -39,24 +39,22 @@ class AbstractDeviceGroup(OrgMixin, TimeStampedEditableModel):
3939
meta_data = JSONField(
4040
blank=True,
4141
default=dict,
42-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
43-
dump_kwargs={"indent": 4},
4442
help_text=_(
4543
"Group meta data, use this field to store data which is related"
4644
" to this group and can be retrieved via the REST API."
4745
),
4846
verbose_name=_("Metadata"),
47+
encoder=DjangoJSONEncoder,
4948
)
5049
context = JSONField(
5150
blank=True,
5251
default=dict,
53-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
54-
dump_kwargs={"indent": 4},
5552
help_text=_(
5653
"This field can be used to add meta data for the group"
5754
' or to add "Configuration Variables" to the devices.'
5855
),
5956
verbose_name=_("Configuration Variables"),
57+
encoder=DjangoJSONEncoder,
6058
)
6159

6260
def __str__(self):

openwisp_controller/config/base/multitenancy.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import collections
21
from copy import deepcopy
32

43
import swapper
4+
from django.core.serializers.json import DjangoJSONEncoder
55
from django.db import models
6+
from django.db.models import JSONField
67
from django.utils.translation import gettext_lazy as _
7-
from jsonfield import JSONField
88

99
from openwisp_utils.base import KeyField, UUIDModel
1010

@@ -34,12 +34,11 @@ class AbstractOrganizationConfigSettings(UUIDModel):
3434
context = JSONField(
3535
blank=True,
3636
default=dict,
37-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
38-
dump_kwargs={"indent": 4},
3937
help_text=_(
4038
'This field can be used to add "Configuration Variables"' " to the devices."
4139
),
4240
verbose_name=_("Configuration Variables"),
41+
encoder=DjangoJSONEncoder,
4342
)
4443

4544
class Meta:

openwisp_controller/config/base/template.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
from copy import copy
55

66
from django.core.exceptions import ObjectDoesNotExist, ValidationError
7+
from django.core.serializers.json import DjangoJSONEncoder
78
from django.db import models, transaction
9+
from django.db.models import JSONField
810
from django.utils.translation import gettext_lazy as _
9-
from jsonfield import JSONField
1011
from netjsonconfig.exceptions import ValidationError as NetjsonconfigValidationError
1112
from swapper import get_model_name, load_model
1213
from taggit.managers import TaggableManager
@@ -102,8 +103,7 @@ class AbstractTemplate(ShareableOrgMixinUniqueName, BaseConfig):
102103
"template; these default variables will "
103104
"be used during schema validation."
104105
),
105-
load_kwargs={"object_pairs_hook": OrderedDict},
106-
dump_kwargs={"indent": 4},
106+
encoder=DjangoJSONEncoder,
107107
)
108108
__template__ = True
109109

openwisp_controller/config/migrations/0001_squashed_0002_config_settings_uuid.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
# -*- coding: utf-8 -*-
22
# Generated by Django 1.10.5 on 2017-05-03 17:54
33

4-
import collections
54
import re
65
import uuid
76

87
import django.core.validators
98
import django.utils.timezone
10-
import jsonfield.fields
119
import model_utils.fields
1210
from django.conf import settings
1311
from django.db import migrations, models
@@ -58,12 +56,10 @@ class Migration(migrations.Migration):
5856
),
5957
(
6058
"config",
61-
jsonfield.fields.JSONField(
59+
models.JSONField(
6260
blank=True,
6361
default=dict,
64-
dump_kwargs={"ensure_ascii": False, "indent": 4},
6562
help_text="configuration in NetJSON DeviceConfiguration format",
66-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
6763
verbose_name="configuration",
6864
),
6965
),
@@ -250,12 +246,10 @@ class Migration(migrations.Migration):
250246
),
251247
(
252248
"config",
253-
jsonfield.fields.JSONField(
249+
models.JSONField(
254250
blank=True,
255251
default=dict,
256-
dump_kwargs={"ensure_ascii": False, "indent": 4},
257252
help_text="configuration in NetJSON DeviceConfiguration format",
258-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
259253
verbose_name="configuration",
260254
),
261255
),
@@ -347,11 +341,9 @@ class Migration(migrations.Migration):
347341
("name", models.CharField(max_length=64, unique=True)),
348342
(
349343
"config",
350-
jsonfield.fields.JSONField(
344+
models.JSONField(
351345
default=dict,
352-
dump_kwargs={"ensure_ascii": False, "indent": 4},
353346
help_text="configuration in NetJSON DeviceConfiguration format",
354-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
355347
verbose_name="configuration",
356348
),
357349
),

openwisp_controller/config/migrations/0018_config_context.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# Generated by Django 2.1.4 on 2019-01-09 01:52
22

3-
import collections
43

5-
import jsonfield.fields
6-
from django.db import migrations
4+
from django.db import migrations, models
75

86

97
class Migration(migrations.Migration):
@@ -13,15 +11,13 @@ class Migration(migrations.Migration):
1311
migrations.AddField(
1412
model_name="config",
1513
name="context",
16-
field=jsonfield.fields.JSONField(
14+
field=models.JSONField(
1715
blank=True,
18-
dump_kwargs={"indent": 4},
1916
help_text=(
2017
'Additional <a href="http://netjsonconfig.openwisp.org'
2118
'/en/stable/general/basics.html#context" target="_blank">context '
2219
"(configuration variables)</a> in JSON format"
2320
),
24-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
2521
null=True,
2622
),
2723
)
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# Generated by Django 3.0.3 on 2020-02-26 19:58
22

3-
import collections
43

5-
import jsonfield.fields
6-
from django.db import migrations
4+
from django.db import migrations, models
75

86

97
class Migration(migrations.Migration):
@@ -13,16 +11,14 @@ class Migration(migrations.Migration):
1311
migrations.AlterField(
1412
model_name="config",
1513
name="context",
16-
field=jsonfield.fields.JSONField(
14+
field=models.JSONField(
1715
blank=True,
1816
default=dict,
19-
dump_kwargs={"ensure_ascii": False, "indent": 4},
2017
help_text=(
2118
'Additional <a href="http://netjsonconfig.openwisp.org'
2219
'/en/stable/general/basics.html#context" target="_blank">'
2320
"context (configuration variables)</a> in JSON format"
2421
),
25-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
2622
),
2723
)
2824
]

openwisp_controller/config/migrations/0028_template_default_values.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# Generated by Django 3.0.3 on 2020-06-29 23:54
22

3-
import collections
43

5-
import jsonfield.fields
6-
from django.db import migrations
4+
from django.db import migrations, models
75

86

97
class Migration(migrations.Migration):
@@ -13,16 +11,14 @@ class Migration(migrations.Migration):
1311
migrations.AddField(
1412
model_name="template",
1513
name="default_values",
16-
field=jsonfield.fields.JSONField(
14+
field=models.JSONField(
1715
blank=True,
1816
default=dict,
19-
dump_kwargs={"ensure_ascii": False, "indent": 4},
2017
help_text=(
2118
"A dictionary containing the default values for "
2219
"the variables used by this template; these default "
2320
"variables will be used during schema validation."
2421
),
25-
load_kwargs={"object_pairs_hook": collections.OrderedDict},
2622
verbose_name="Default Values",
2723
),
2824
)

0 commit comments

Comments
 (0)