Add basic LMOTFY endpoint

This commit is contained in:
Jake Howard 2022-08-23 14:56:05 +01:00
parent f140e8107d
commit d46fab9bdc
Signed by: jake
GPG key ID: 57AFB45680EDD477
5 changed files with 62 additions and 1 deletions

22
website/api/filters.py Normal file
View file

@ -0,0 +1,22 @@
from typing import Any
from django.db.models import Value
from django.http.request import HttpRequest
from rest_framework.filters import SearchFilter
from wagtail.query import PageQuerySet
from wagtail.search.utils import parse_query_string
class WagtailSearchFilter(SearchFilter):
def filter_queryset(
self, request: HttpRequest, queryset: PageQuerySet, view: Any
) -> PageQuerySet:
search_query = request.query_params.get(self.search_param, "")
if not search_query:
return queryset.annotate(relevance=Value(0)).none()
filters, query = parse_query_string(search_query)
results = queryset.search(query).annotate_score("relevance")
return results.get_queryset()

View file

@ -0,0 +1,6 @@
from rest_framework.pagination import PageNumberPagination
class CustomPageNumberPagination(PageNumberPagination):
page_size = 20
max_page_size = 50

View file

@ -1,6 +1,8 @@
from rest_framework import serializers from rest_framework import serializers
from wagtail.models import Page from wagtail.models import Page
from website.blog.models import BlogPostListPage
class PageLinkSerializer(serializers.ModelSerializer): class PageLinkSerializer(serializers.ModelSerializer):
full_url = serializers.SerializerMethodField() full_url = serializers.SerializerMethodField()
@ -11,3 +13,14 @@ class PageLinkSerializer(serializers.ModelSerializer):
def get_full_url(self, page: Page) -> str: def get_full_url(self, page: Page) -> str:
return page.get_full_url(request=self.context["request"]) return page.get_full_url(request=self.context["request"])
class LMOTFYSerializer(serializers.ModelSerializer):
full_url = serializers.SerializerMethodField()
class Meta:
model = BlogPostListPage
fields = read_only_fields = ["full_url", "title", "summary"]
def get_full_url(self, page: Page) -> str:
return page.get_full_url(request=self.context["request"])

View file

@ -11,6 +11,7 @@ app_name = "api"
api_urlpatterns = [ api_urlpatterns = [
path("ping", views.PingAPIView.as_view(), name="ping"), path("ping", views.PingAPIView.as_view(), name="ping"),
path("page-links", views.PageLinksAPIView.as_view(), name="page-links"), path("page-links", views.PageLinksAPIView.as_view(), name="page-links"),
path("lmotfy", views.LMOTFYAPIView.as_view(), name="lmotfy"),
] ]
schema_view = get_schema_view( schema_view = get_schema_view(

View file

@ -1,11 +1,15 @@
from django.http.request import HttpRequest from django.http.request import HttpRequest
from rest_framework.filters import OrderingFilter
from rest_framework.generics import ListAPIView from rest_framework.generics import ListAPIView
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from wagtail.models import Page from wagtail.models import Page
from wagtail.query import PageQuerySet from wagtail.query import PageQuerySet
from . import serializers from website.blog.models import BlogPostListPage
from . import filters, serializers
from .pagination import CustomPageNumberPagination
class PingAPIView(APIView): class PingAPIView(APIView):
@ -27,3 +31,18 @@ class PageLinksAPIView(ListAPIView):
.only("id", "url_path", "title") .only("id", "url_path", "title")
.order_by("title") .order_by("title")
) )
class LMOTFYAPIView(ListAPIView):
"""
Let Me Orange That For You
"""
filter_backends = [filters.WagtailSearchFilter, OrderingFilter]
serializer_class = serializers.LMOTFYSerializer
ordering_fields = ["title", "date", "relevance"]
ordering = ["relevance"]
pagination_class = CustomPageNumberPagination
def get_queryset(self) -> PageQuerySet:
return BlogPostListPage.objects.live().only("id", "url_path", "title", "body")