-
Notifications
You must be signed in to change notification settings - Fork 2
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: Enable Wagtail API #3399
base: master
Are you sure you want to change the base?
feat: Enable Wagtail API #3399
Changes from all commits
eeb6d3e
7183f21
18ba8a4
d8f5b04
f092701
f0f38e7
aa0d5bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add module, class, and method docs at all places. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from django.db.models import F | ||
from rest_framework.permissions import IsAdminUser | ||
from wagtail.api.v2.router import WagtailAPIRouter | ||
from wagtail.api.v2.views import PagesAPIViewSet | ||
from wagtail.images.api.v2.views import ImagesAPIViewSet | ||
from wagtail.documents.api.v2.views import DocumentsAPIViewSet | ||
|
||
from .wagtail_api_filters import ReadableIDFilter | ||
|
||
|
||
class AdminOnlyViewSetMixin: | ||
permission_classes = (IsAdminUser,) | ||
|
||
|
||
class CustomPagesAPIViewSet(AdminOnlyViewSetMixin, PagesAPIViewSet): | ||
filter_backends = [ReadableIDFilter] + PagesAPIViewSet.filter_backends | ||
meta_fields = PagesAPIViewSet.meta_fields + ["live", "last_published_at"] | ||
listing_default_fields = PagesAPIViewSet.listing_default_fields + [ | ||
"live", | ||
"last_published_at", | ||
] | ||
known_query_parameters = PagesAPIViewSet.known_query_parameters.union( | ||
["readable_id"] | ||
) | ||
|
||
def get_queryset(self): | ||
queryset = super().get_queryset() | ||
model_type = self.request.GET.get("type", None) | ||
if model_type == "cms.CoursePage": | ||
queryset = queryset.annotate(readable_id=F("course__readable_id")) | ||
elif model_type == "cms.ProgramPage": | ||
queryset = queryset.annotate(readable_id=F("program__readable_id")) | ||
return queryset | ||
|
||
|
||
class CustomImagesAPIViewSet(AdminOnlyViewSetMixin, ImagesAPIViewSet): | ||
pass | ||
|
||
|
||
class CustomDocumentsAPIViewSet(AdminOnlyViewSetMixin, DocumentsAPIViewSet): | ||
pass | ||
|
||
|
||
api_router = WagtailAPIRouter("wagtailapi") | ||
api_router.register_endpoint("pages", CustomPagesAPIViewSet) | ||
api_router.register_endpoint("images", CustomImagesAPIViewSet) | ||
api_router.register_endpoint("documents", CustomDocumentsAPIViewSet) | ||
Comment on lines
+44
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do this in the urls.py.
Comment on lines
+45
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about we add a URL above the pages that would look like: api/v2/courses/<READABLE_ID>, Then our custom viewset can handle the readable ID and filter the data for us? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from rest_framework.filters import BaseFilterBackend | ||
|
||
|
||
class ReadableIDFilter(BaseFilterBackend): | ||
def filter_queryset(self, request, queryset, view): | ||
field_name = "readable_id" | ||
if field_name in request.GET: | ||
value = request.GET[field_name].replace(" ", "+") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any specific cases that we are trying to handle here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. readable_id is usually of this form |
||
queryset = queryset.filter(**{field_name: value}) | ||
return queryset |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from rest_framework.fields import Field | ||
|
||
from wagtail.models import Page | ||
from wagtail.api.v2.serializers import get_serializer_class | ||
from wagtail.api.v2.views import PagesAPIViewSet | ||
|
||
|
||
class ProductChildPageSerializer(Field): | ||
def to_representation(self, value): | ||
if hasattr(value, "all"): | ||
base_context = {"view": PagesAPIViewSet()} | ||
context = {**base_context, **getattr(self, "context", {})} | ||
return [self.serialize_page(page, context) for page in value.all()] | ||
return self.serialize_page(value, self.context) | ||
|
||
def serialize_page(self, page, context): | ||
if not isinstance(page, Page): | ||
return None | ||
|
||
model = page.specific.__class__ | ||
|
||
serializer = get_serializer_class( | ||
model, | ||
PagesAPIViewSet.body_fields + PagesAPIViewSet.meta_fields, | ||
PagesAPIViewSet.meta_fields, | ||
base=PagesAPIViewSet.base_serializer_class, | ||
) | ||
|
||
return serializer(page.specific, context=context).data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current API does not return the custom page fields like: subhead etc. We should return the custom page data + child page fields as well.