Skip to content

Commit

Permalink
Merge pull request #23 from ubuntu-robotics/refactor/applications_model
Browse files Browse the repository at this point in the history
Refactor/applications model
  • Loading branch information
Guillaumebeuzeboc authored Mar 19, 2024
2 parents 24bff32 + 312fe88 commit 4a6bd17
Show file tree
Hide file tree
Showing 29 changed files with 666 additions and 302 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ lint: ## Run pep8, black, mypy linters.

.PHONY: test
test: lint ## Run tests and generate coverage report.
$(ENV_PREFIX)coverage run --source='.' cos_registration_server/manage.py test api devices
$(ENV_PREFIX)coverage run --source='.' cos_registration_server/manage.py test api devices applications
$(ENV_PREFIX)coverage xml
$(ENV_PREFIX)coverage html

Expand Down
1 change: 1 addition & 0 deletions cos_registration_server/api/apps.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""API apps."""

from django.apps import AppConfig


Expand Down
51 changes: 0 additions & 51 deletions cos_registration_server/api/grafana_dashboards.py

This file was deleted.

1 change: 0 additions & 1 deletion cos_registration_server/api/management/__init__.py

This file was deleted.

This file was deleted.

This file was deleted.

143 changes: 110 additions & 33 deletions cos_registration_server/api/serializer.py
Original file line number Diff line number Diff line change
@@ -1,64 +1,141 @@
"""API app serializer."""

import json

from applications.models import Dashboard, GrafanaDashboard
from devices.models import Device
from rest_framework import serializers
from rest_framework.validators import UniqueValidator


class DeviceSerializer(serializers.Serializer):
"""Device Serializer class."""

uid = serializers.CharField(
required=True,
validators=[UniqueValidator(queryset=Device.objects.all())],
)
creation_date = serializers.DateTimeField(read_only=True)
address = serializers.IPAddressField(required=True)
grafana_dashboards = serializers.JSONField(required=False)
class DashboardSerializer:
"""Dashboard Serializer class."""

def create(self, validated_data):
"""Create Device object from data.
class Meta:
"""DashboardSerializer Meta class."""

validated_data: Dict of complete and validated data.
"""
return Device.objects.create(**validated_data)
model = Dashboard
fields = ["uid", "dashboard"]

def update(self, instance, validated_data):
"""Update a Device from data.
"""Update a Dashboard from data.
instance: Device instance.
validated_data: Dict of partial and validated data.
"""
address = validated_data.get("address", instance.address)
instance.address = address
grafana_dashboards = validated_data.get(
"grafana_dashboards", instance.grafana_dashboards
)
instance.grafana_dashboards = grafana_dashboards
dashboard = validated_data.get("dashboard", instance.dashboard)
instance.dashboard = dashboard
instance.save()
return instance

def validate_grafana_dashboards(self, value):
"""Validate grafana dashboards data.
def validate_dashboard(self, value):
"""Validate dashboards data.
value: Grafana dashboards provided data.
return: Grafana dashboards as list.
value: dashboard provided data.
return: dashboard json.
raise:
json.JSONDecodeError
serializers.ValidationError
"""
if isinstance(value, str):
try:
dashboards = json.loads(value)
dashboard = json.loads(value)
except json.JSONDecodeError:
raise serializers.ValidationError(
"Failed to load grafana_dashboards as json."
"Failed to load dashboard as json."
)
else:
dashboards = value
if not isinstance(dashboards, list):
dashboard = value
if not isinstance(dashboard, dict):
raise serializers.ValidationError(
"gafana_dashboards is not a supported format (list)."
"Dashboard is not a supported format (dict)."
)
return dashboards
return dashboard


class GrafanaDashboardSerializer(
DashboardSerializer, serializers.ModelSerializer
):
"""Grafana Dashboard Serializer class."""

class Meta(DashboardSerializer.Meta):
"""DashboardSerializer Meta class."""

model = GrafanaDashboard

def create(self, validated_data):
"""Create Grafana Dashboard object from data.
validated_data: Dict of complete and validated data.
"""
return GrafanaDashboard.objects.create(**validated_data)


class DeviceSerializer(serializers.ModelSerializer):
"""Device Serializer class."""

grafana_dashboards = serializers.SlugRelatedField(
many=True,
queryset=GrafanaDashboard.objects.all(),
slug_field="uid",
required=False,
)

class Meta:
"""DeviceSerializer Meta class."""

model = Device
fields = ("uid", "creation_date", "address", "grafana_dashboards")

def create(self, validated_data):
"""Create Device object from data.
validated_data: Dict of complete and validated data.
"""
grafana_dashboards_data = validated_data.pop("grafana_dashboards", {})
device = Device.objects.create(**validated_data)

for dashboard_uid in grafana_dashboards_data:
try:
dashboard = GrafanaDashboard.objects.get(uid=dashboard_uid)
device.grafana_dashboards.add(dashboard)
except GrafanaDashboard.DoesNotExist:
raise serializers.ValidationError(
f"GrafanaDashboard with UID {dashboard_uid}"
" does not exist."
)
return device

def update(self, instance, validated_data):
"""Update a Device from data.
instance: Device instance.
validated_data: Dict of partial and validated data.
"""
# Update device fields (if any)
for field, value in validated_data.items():
if field != "grafana_dashboards":
setattr(instance, field, value)
instance.save()

# Update Grafana dashboards
try:
grafana_dashboards_data = validated_data.pop("grafana_dashboards")
current_grafana_dashboards = instance.grafana_dashboards.all()
for dashboard in current_grafana_dashboards:
instance.grafana_dashboards.remove(dashboard)

for dashboard_uid in grafana_dashboards_data:
try:
dashboard = GrafanaDashboard.objects.get(uid=dashboard_uid)
instance.grafana_dashboards.add(dashboard)
except GrafanaDashboard.DoesNotExist:
raise serializers.ValidationError(
f"Grafana Dashboard with UID {dashboard_uid}"
" does not exist."
)
except KeyError:
# Handle partial updates without grafana_dashboards vs
# empty grafana_dashboards
pass

return instance
Loading

0 comments on commit 4a6bd17

Please sign in to comment.