Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Paginated module device reading endpoint #12

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
6 changes: 6 additions & 0 deletions shedpi_hub_dashboard/pagination.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from rest_framework.pagination import CursorPagination


class CreatedAtBasedCursorPagination(CursorPagination):
ordering = "-created_at"
page_size_query_param = "page_size"
10 changes: 9 additions & 1 deletion shedpi_hub_dashboard/serlializers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import ClassVar

from rest_framework import serializers

from .models import DeviceModule, DeviceModuleReading
Expand All @@ -13,4 +15,10 @@ class DeviceModuleReadingSerializer(serializers.ModelSerializer):
class Meta:
model = DeviceModuleReading
fields = "__all__"
# extra_kwargs = {"device_module": {"required": True}}
extra_kwargs: ClassVar[dict] = {"device_module": {"required": True}}


class DeviceModuleReadingListSerializer(serializers.ModelSerializer):
class Meta:
model = DeviceModuleReading
exclude: ClassVar[list] = ["device_module"]
54 changes: 53 additions & 1 deletion shedpi_hub_dashboard/tests/unit/test_endpoints.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import json

import pytest
from django.urls import reverse
from rest_framework import status
from rest_framework.exceptions import ValidationError
from rest_framework.reverse import reverse

from shedpi_hub_dashboard.models import DeviceModuleReading
from shedpi_hub_dashboard.tests.utils.factories import (
Expand Down Expand Up @@ -50,6 +51,57 @@ def test_device_module_readings_list(client):
assert len(response.data) == 2


@pytest.mark.django_db
def test_device_module_readings_list_pagination(client):
"""
An individual device module readings are returned from the module readings endpoint
"""
schema = {
"$id": "https://example.com/person.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Reading",
"type": "object",
"properties": {
"temperature": {"type": "string", "description": "The Temperature"},
},
}
device_module = DeviceModuleFactory(schema=schema)
DeviceModuleReadingFactory.create_batch(
110, device_module=device_module, data={"temperature": "20"}
)

url = reverse("devicemodulereading-paginated-list")
response = client.get(url, data={"device_module": device_module.id})

assert response.status_code == status.HTTP_200_OK
assert len(response.data["results"]) == 100


@pytest.mark.django_db
def test_device_module_readings_list_pagination_no_module_supplied(client):
"""
When no module is supplied the user should be supplied a valida tion message telling them so
"""
schema = {
"$id": "https://example.com/person.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Reading",
"type": "object",
"properties": {
"temperature": {"type": "string", "description": "The Temperature"},
},
}
device_module = DeviceModuleFactory(schema=schema)
DeviceModuleReadingFactory.create_batch(
110, device_module=device_module, data={"temperature": "20"}
)

url = reverse("devicemodulereading-paginated-list")

with pytest.raises(ValidationError):
client.get(url)


@pytest.mark.django_db
def test_device_module_readings_list_no_device_module_supplied(client):
""" """
Expand Down
51 changes: 32 additions & 19 deletions shedpi_hub_dashboard/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
from django.template.response import TemplateResponse
from rest_framework import viewsets
from rest_framework import mixins, viewsets
from rest_framework.exceptions import ValidationError
from rest_framework.viewsets import GenericViewSet

from .models import DeviceModule, DeviceModuleReading
from .serlializers import DeviceModuleReadingSerializer, DeviceModuleSerializer
from .pagination import CreatedAtBasedCursorPagination
from .serlializers import (
DeviceModuleReadingListSerializer,
DeviceModuleReadingSerializer,
DeviceModuleSerializer,
)


def index(request):
Expand All @@ -19,6 +26,11 @@ class DeviceModuleReadingViewSet(viewsets.ModelViewSet):
queryset = DeviceModuleReading.objects.all()
serializer_class = DeviceModuleReadingSerializer

def get_serializer_class(self):
if hasattr(self, "action") and self.action == "list":
return DeviceModuleReadingListSerializer
return DeviceModuleReadingSerializer

def get_queryset(self):
# FIXME: Validate that the user supplied this get param!
device_module_id = self.request.query_params.get("device_module")
Expand All @@ -28,20 +40,21 @@ def get_queryset(self):

return self.queryset

# def list(self, request):
# queryset = self.get_queryset()
#
# context = {"request": request}
# device_module_id = self.request.query_params.get("device_module")
#
# if device_module_id:
# queryset = queryset.filter(device_module=device_module_id)
#
# context["device_module"] = device_module_id
#
# context["queryset"] = queryset
#
# serializer = self.get_serializer(data=request.data, context=context)
# serializer.is_valid(raise_exception=True)
#
# return Response(serializer.data)

class DeviceModuleReadingPaginatedViewSet(
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
GenericViewSet,
):
queryset = DeviceModuleReading.objects.all()
serializer_class = DeviceModuleReadingListSerializer
pagination_class = CreatedAtBasedCursorPagination

def get_queryset(self):
device_module_id = self.request.query_params.get("device_module")

if not device_module_id:
raise ValidationError({"device_module": "Not supplied"})

return self.queryset.filter(device_module=device_module_id)
1 change: 1 addition & 0 deletions shedpi_hub_example_project/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,5 @@
# "DEFAULT_PERMISSION_CLASSES": [
# "rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly"
# ]
"PAGE_SIZE": 100,
}
11 changes: 10 additions & 1 deletion shedpi_hub_example_project/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@
from django.urls import include, path
from rest_framework import routers

from shedpi_hub_dashboard.views import DeviceModuleReadingViewSet, DeviceModuleViewSet
from shedpi_hub_dashboard.views import (
DeviceModuleReadingPaginatedViewSet,
DeviceModuleReadingViewSet,
DeviceModuleViewSet,
)

router = routers.DefaultRouter()
router.register(r"device-module", DeviceModuleViewSet)
router.register(r"device-module-readings", DeviceModuleReadingViewSet)
router.register(
r"device-module-readings-paginated",
DeviceModuleReadingPaginatedViewSet,
basename="devicemodulereading-paginated",
)

urlpatterns = [
*[
Expand Down
Loading