Skip to content

Commit 85f5be9

Browse files
committed
[chores] Clean up
1 parent f2856b5 commit 85f5be9

File tree

7 files changed

+48
-99
lines changed

7 files changed

+48
-99
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ jobs:
7676
pip install -U -r requirements-test.txt
7777
pip install -U -e .
7878
pip install ${{ matrix.django-version }}
79-
pip install -U --force-reinstall --no-deps https://github.com/openwisp/openwisp-utils/tarball/exclude_validation
8079
8180
- name: Start postgres and redis
8281
if: ${{ !cancelled() && steps.deps.conclusion == 'success' }}

openwisp_controller/config/api/serializers.py

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from copy import deepcopy
2-
31
from django.core.exceptions import ValidationError
42
from django.db import transaction
53
from django.db.models import Q
@@ -9,7 +7,7 @@
97

108
from openwisp_utils.api.serializers import ValidatedModelSerializer
119

12-
from ...serializers import BaseSerializer, ValidatedDeviceIdSerializer
10+
from ...serializers import BaseSerializer
1311
from .. import settings as app_settings
1412

1513
Template = load_model('config', 'Template')
@@ -106,7 +104,10 @@ def get_queryset(self):
106104
return queryset
107105

108106

109-
class BaseConfigSerializer(ValidatedDeviceIdSerializer):
107+
class BaseConfigSerializer(ValidatedModelSerializer):
108+
# The device object is excluded from validation
109+
# because this serializer focuses on validating
110+
# config objects.
110111
exclude_validation = ['device']
111112

112113
class Meta:
@@ -127,22 +128,12 @@ def validate(self, data):
127128
config object pointing to an existing device,
128129
the validation will fail because a config object
129130
for this device already exists (due to one-to-one relationship).
130-
131-
For new devices, the device hasn't been created yet,
132-
so we have to exclude the `device` field from validation.
133131
"""
134-
# Existing device
135132
device = self.context.get('device')
136-
# data.pop('device', None)
137-
# import ipdb; ipdb.set_trace()
138133
if not self.instance and device:
139134
# Existing device with existing config
140-
# Or it's an exsiting device with a new config
141135
if device._has_config():
142136
self.instance = device.config
143-
# return super().validate(data)
144-
# New device
145-
# self.exclude_validation = ['device']
146137
return super().validate(data)
147138

148139

@@ -216,10 +207,6 @@ def _update_config(self, device, config_data):
216207
except ValidationError as error:
217208
raise serializers.ValidationError({'config': error.messages})
218209

219-
# def run_validation(self, *args, **kwargs):
220-
# import ipdb; ipdb.set_trace()
221-
# return super().run_validation(*args, **kwargs)
222-
223210

224211
class DeviceListConfigSerializer(BaseConfigSerializer):
225212
config = serializers.JSONField(
@@ -286,10 +273,6 @@ class DeviceDetailConfigSerializer(BaseConfigSerializer):
286273
)
287274
templates = FilterTemplatesByOrganization(many=True)
288275

289-
# def validate(self, *args, **kwargs):
290-
# import ipdb; ipdb.set_trace()
291-
# return super().validate(*args, **kwargs)
292-
293276

294277
class DeviceDetailSerializer(DeviceConfigSerializer):
295278
config = DeviceDetailConfigSerializer(allow_null=True)
@@ -316,10 +299,6 @@ class Meta(BaseMeta):
316299
'modified',
317300
]
318301

319-
# def to_internal_value(self, *args, **kwargs):
320-
# import ipdb; ipdb.set_trace()
321-
# return super().to_internal_value(*args, **kwargs)
322-
323302
def update(self, instance, validated_data):
324303
config_data = validated_data.pop('config', {})
325304
raw_data_for_signal_handlers = {

openwisp_controller/config/api/views.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,20 +114,17 @@ def perform_destroy(self, instance):
114114
force_deletion = self.request.query_params.get('force', None) == 'true'
115115
instance.delete(check_deactivated=(not force_deletion))
116116

117-
# def update(self, request, *args, **kwargs):
118-
# import ipdb; ipdb.set_trace()
119-
# partial = kwargs.pop('partial', False)
120-
# instance = self.get_object()
121-
# serializer = self.get_serializer(instance, data=request.data, partial=partial)
122-
# serializer.is_valid(raise_exception=True)
123-
# self.perform_update(serializer)
124-
#
125-
# if getattr(instance, '_prefetched_objects_cache', None):
126-
# # If 'prefetch_related' has been applied to a queryset, we need to
127-
# # forcibly invalidate the prefetch cache on the instance.
128-
# instance._prefetched_objects_cache = {}
129-
#
130-
# return Response(serializer.data)
117+
def get_object(self):
118+
"""Set device property for serializer context."""
119+
obj = super().get_object()
120+
self.device = obj
121+
return obj
122+
123+
def get_serializer_context(self):
124+
"""Add device to serializer context for validation purposes."""
125+
context = super().get_serializer_context()
126+
context['device'] = self.device
127+
return context
131128

132129

133130
class DeviceActivateView(ProtectedAPIMixin, GenericAPIView):

openwisp_controller/connection/api/serializers.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
from rest_framework import serializers
22
from swapper import load_model
33

4-
from ...serializers import (
5-
BaseDeviceIdSerializer,
6-
BaseSerializer,
7-
ValidatedDeviceIdSerializer,
8-
)
4+
from openwisp_users.api.mixins import FilterSerializerByOrgManaged
5+
from openwisp_utils.api.serializers import ValidatedModelSerializer
6+
7+
from ...serializers import BaseSerializer
98

109
Command = load_model('connection', 'Command')
1110
DeviceConnection = load_model('connection', 'DeviceConnection')
1211
Credentials = load_model('connection', 'Credentials')
1312
Device = load_model('config', 'Device')
1413

1514

16-
class CommandSerializer(ValidatedDeviceIdSerializer):
15+
class ValidatedDeviceFieldSerializer(ValidatedModelSerializer):
16+
def validate(self, data):
17+
# Add "device_id" to the data for validation
18+
data['device_id'] = self.context['device_id']
19+
return super().validate(data)
20+
21+
22+
class CommandSerializer(ValidatedDeviceFieldSerializer):
1723
input = serializers.JSONField(allow_null=True)
1824
device = serializers.PrimaryKeyRelatedField(
1925
read_only=True, pk_field=serializers.UUIDField(format='hex_verbose')
@@ -61,7 +67,9 @@ class Meta:
6167
read_only_fields = ('created', 'modified')
6268

6369

64-
class DeviceConnectionSerializer(BaseDeviceIdSerializer):
70+
class DeviceConnectionSerializer(
71+
FilterSerializerByOrgManaged, ValidatedDeviceFieldSerializer
72+
):
6573
class Meta:
6674
model = DeviceConnection
6775
fields = (
@@ -81,9 +89,3 @@ class Meta:
8189
'is_working': {'read_only': True},
8290
}
8391
read_only_fields = ('created', 'modified')
84-
85-
# def validate(self, data):
86-
# data['device'] = Device.objects.get(pk=self.context['device_id'])
87-
# instance = self.instance or self.Meta.model(**data)
88-
# instance.full_clean()
89-
# return data

openwisp_controller/connection/base/models.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,18 @@ def __str__(self):
458458
return f'«{command}» {sent} {created.strftime("%d %b %Y at %I:%M %p")}'
459459

460460
def clean(self):
461+
self._verify_command_type_allowed()
462+
try:
463+
jsonschema.Draft4Validator(self._schema).validate(self.input)
464+
except SchemaError as e:
465+
raise ValidationError({'input': e.message})
466+
467+
def _verify_command_type_allowed(self):
468+
"""Raises validation error if command type is not allowed."""
469+
# if device is not set, skip to avoid uncaught exception
470+
# (standard model validation will kick in)
471+
if not hasattr(self, 'device'):
472+
return
461473
if self.type not in self.get_org_choices(
462474
organization_id=self.device.organization_id
463475
):
@@ -471,10 +483,6 @@ def clean(self):
471483
)
472484
}
473485
)
474-
try:
475-
jsonschema.Draft4Validator(self._schema).validate(self.input)
476-
except SchemaError as e:
477-
raise ValidationError({'input': e.message})
478486

479487
@property
480488
def is_custom(self):

openwisp_controller/connection/tests/test_api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ def test_put_devceconnection_detail(self):
503503
'enabled': False,
504504
'failure_reason': '',
505505
}
506-
with self.assertNumQueries(15):
506+
with self.assertNumQueries(14):
507507
response = self.client.put(path, data, content_type='application/json')
508508
self.assertEqual(response.status_code, 200)
509509
self.assertEqual(
@@ -517,7 +517,7 @@ def test_patch_deviceconnectoin_detail(self):
517517
path = reverse('connection_api:deviceconnection_detail', args=(d1, dc.pk))
518518
self.assertEqual(dc.update_strategy, app_settings.UPDATE_STRATEGIES[0][0])
519519
data = {'update_strategy': app_settings.UPDATE_STRATEGIES[1][0]}
520-
with self.assertNumQueries(14):
520+
with self.assertNumQueries(13):
521521
response = self.client.patch(path, data, content_type='application/json')
522522
self.assertEqual(response.status_code, 200)
523523
self.assertEqual(

openwisp_controller/serializers.py

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,11 @@
22
from openwisp_utils.api.serializers import ValidatedModelSerializer
33

44

5-
class ValidatedDeviceIdSerializer(ValidatedModelSerializer):
6-
pass
7-
# def validate(self, data):
8-
# """Adds "device" to the data dictionary.
9-
#
10-
# Used to satisfy validation needs."""
11-
# # for key in ['device', 'device_id']:
12-
# # if key in self.context:
13-
# # data[key] = self.context[key]
14-
# if 'device' in self.context:
15-
# data['device'] = self.context['device']
16-
# data = super().validate(data)
17-
# data.pop('device', None)
18-
# return data
19-
20-
215
class BaseSerializer(FilterSerializerByOrgManaged, ValidatedModelSerializer):
22-
"""
23-
TODO
24-
"""
25-
26-
pass
6+
"""BaseSerializer for most API endpoints.
277
28-
29-
class BaseDeviceIdSerializer(FilterSerializerByOrgManaged, ValidatedDeviceIdSerializer):
30-
"""
31-
TODO
8+
- FilterSerializerByOrgManaged: for multi-tenancy
9+
- ValidatedModelSerializer: for model validation
3210
"""
3311

3412
pass
35-
36-
37-
class DeviceContextMixin:
38-
"""Adds the device object to the serializer context."""
39-
40-
def get_object(self):
41-
obj = super().get_object()
42-
self.object = obj
43-
return obj
44-
45-
def get_serializer_context(self):
46-
context = super().get_serializer_context()
47-
context['device'] = self.object
48-
return context

0 commit comments

Comments
 (0)