From f140e8107d37c0d145721cbbc3bbc367296e7162 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Tue, 23 Aug 2022 09:23:22 +0100 Subject: [PATCH] Add endpoint to list page URLs I use this for my quick link grabber script --- website/api/serializers.py | 13 +++++++++++++ website/api/tests.py | 29 +++++++++++++++++++++++++++++ website/api/urls.py | 5 ++++- website/api/views.py | 17 +++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 website/api/serializers.py create mode 100644 website/api/tests.py diff --git a/website/api/serializers.py b/website/api/serializers.py new file mode 100644 index 0000000..bd11c08 --- /dev/null +++ b/website/api/serializers.py @@ -0,0 +1,13 @@ +from rest_framework import serializers +from wagtail.models import Page + + +class PageLinkSerializer(serializers.ModelSerializer): + full_url = serializers.SerializerMethodField() + + class Meta: + model = Page + fields = read_only_fields = ["full_url", "title"] + + def get_full_url(self, page: Page) -> str: + return page.get_full_url(request=self.context["request"]) diff --git a/website/api/tests.py b/website/api/tests.py new file mode 100644 index 0000000..dd1e2a0 --- /dev/null +++ b/website/api/tests.py @@ -0,0 +1,29 @@ +from django.urls import reverse +from rest_framework.test import APISimpleTestCase, APITestCase + +from website.common.factories import ContentPageFactory +from website.home.models import HomePage + + +class PingAPIViewTestCase(APISimpleTestCase): + url = reverse("api:ping") + + def test_accessible(self) -> None: + response = self.client.get(self.url) + self.assertEqual(response.status_code, 200) + + +class PageLinksAPIViewTestCase(APITestCase): + url = reverse("api:page-links") + + @classmethod + def setUpTestData(cls) -> None: + cls.home_page = HomePage.objects.get() + + for _ in range(5): + ContentPageFactory(parent=cls.home_page) + + def test_accessible(self) -> None: + with self.assertNumQueries(3): + response = self.client.get(self.url) + self.assertEqual(response.status_code, 200) diff --git a/website/api/urls.py b/website/api/urls.py index 4a90671..ab356b8 100644 --- a/website/api/urls.py +++ b/website/api/urls.py @@ -8,7 +8,10 @@ from . import views app_name = "api" -api_urlpatterns = [path("ping", views.PingAPIView.as_view(), name="ping")] +api_urlpatterns = [ + path("ping", views.PingAPIView.as_view(), name="ping"), + path("page-links", views.PageLinksAPIView.as_view(), name="page-links"), +] schema_view = get_schema_view( openapi.Info( diff --git a/website/api/views.py b/website/api/views.py index 33a1ecc..9362904 100644 --- a/website/api/views.py +++ b/website/api/views.py @@ -1,6 +1,11 @@ from django.http.request import HttpRequest +from rest_framework.generics import ListAPIView from rest_framework.response import Response from rest_framework.views import APIView +from wagtail.models import Page +from wagtail.query import PageQuerySet + +from . import serializers class PingAPIView(APIView): @@ -10,3 +15,15 @@ class PingAPIView(APIView): def get(self, request: HttpRequest) -> Response: return Response("PONG") + + +class PageLinksAPIView(ListAPIView): + serializer_class = serializers.PageLinkSerializer + + def get_queryset(self) -> PageQuerySet: + return ( + Page.objects.live() + .exclude(depth__lte=1) + .only("id", "url_path", "title") + .order_by("title") + )