Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@ jobs:
dj51_cms50.txt,
dj52_cms50.txt,
dj60_cms50.txt,
dj52_cmsmain.txt
]
os: [
ubuntu-latest,
]
exclude:
- python-version: "3.10"
requirements-file: dj60_cms50.txt
- python-version: "3.11"
requirements-file: dj60_cms50.txt
- python-version: "3.14"
requirements-file: dj42_cms41.txt
os: ubuntu-latest
Expand All @@ -47,11 +52,6 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Install system deps (cairo stack)
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential libcairo2-dev pkg-config python3-dev
- name: Install dependencies
run: |
uv venv
Expand Down
16 changes: 16 additions & 0 deletions djangocms_rest/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ def method_schema_decorator(method):
]
)

extend_page_search_schema = extend_schema(
parameters=[
OpenApiParameter(
name="q",
type=OpenApiTypes.STR,
location=OpenApiParameter.QUERY,
description="Search for an exact match of the search term to find pages",
required=False,
),
]
)

except ImportError:

def method_schema_decorator(method):
Expand All @@ -84,3 +96,7 @@ def create_view_with_url_name(view_class, url_name):
def extend_placeholder_schema(func):
"""No-op when drf-spectacular is not available."""
return func

def extend_page_search_schema(func):
"""No-op when drf-spectacular is not available."""
return func
5 changes: 5 additions & 0 deletions djangocms_rest/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
views.PageDetailView.as_view(),
name="page-detail",
),
path(
"<slug:language>/page_search/",
views.PageSearchView.as_view(),
name="page-search",
),
path(
"<slug:language>/placeholders/<int:content_type_id>/<int:object_id>/<str:slot>/",
views.PlaceholderDetailView.as_view(),
Expand Down
17 changes: 15 additions & 2 deletions djangocms_rest/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
get_site_filtered_queryset,
)
from djangocms_rest.views_base import BaseAPIView, BaseListAPIView
from djangocms_rest.schemas import extend_placeholder_schema, menu_schema_class

from djangocms_rest.schemas import extend_placeholder_schema, extend_page_search_schema, menu_schema_class

# Generate the plugin definitions once at module load time
# This avoids the need to import the plugin definitions in every view
Expand Down Expand Up @@ -85,6 +84,20 @@ def get_queryset(self):
raise NotFound()


class PageSearchView(PageListView):
@extend_page_search_schema
def get(self, request, language: str | None = None) -> Response:
self.search_term = request.GET.get("q", "")
self.language = language
return super().get(request)

def get_queryset(self):
if not self.search_term:
return PageContent.objects.none()
qs = Page.objects.search(self.search_term, language=self.language, current_site_only=False).on_site(self.site)
return PageContent.objects.filter(page__in=qs).distinct()


class PageTreeListView(BaseAPIView):
permission_classes = [IsAllowedPublicLanguage]
serializer_class = PageMetaSerializer
Expand Down
52 changes: 43 additions & 9 deletions tests/endpoints/test_page_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,54 @@ def test_get_paginated_list(self):
self.assertEqual(response.status_code, 404)

# GET PREVIEW
response = self.client.get(
reverse("page-list", kwargs={"language": "en"}) + "?preview"
)
response = self.client.get(reverse("page-list", kwargs={"language": "en"}) + "?preview")
self.assertEqual(response.status_code, 403)

response = self.client.get(
reverse("page-list", kwargs={"language": "xx"}) + "?preview"
)
response = self.client.get(reverse("page-list", kwargs={"language": "xx"}) + "?preview")
self.assertEqual(response.status_code, 403)

# GET PREVIEW - Protected
def test_get_protected(self):
self.client.force_login(self.user)
response = self.client.get(
reverse("page-list", kwargs={"language": "en"}) + "?preview"
)
response = self.client.get(reverse("page-list", kwargs={"language": "en"}) + "?preview")
self.assertEqual(response.status_code, 200)

def test_page_search(self):
for page in self.pages:
page_content = page.get_admin_content("en")
if hasattr(page_content, "versions"):
page_content.versions.first().publish(self.get_superuser())

# GET
response = self.client.get(reverse("page-search", kwargs={"language": "en"}) + "?q=1")
self.assertEqual(response.status_code, 200)
data = response.json()
results = data["results"]

# Validate REST Pagination Attributes
self.assertIn("count", data)
self.assertIn("next", data)
self.assertIn("previous", data)
self.assertIn("results", data)
self.assertIsInstance(results, list)
self.assertEqual(data["count"], 4)

def test_empty_page_search(self):
for page in self.pages:
page_content = page.get_admin_content("en")
if hasattr(page_content, "versions"):
page_content.versions.first().publish(self.get_superuser())

# GET
response = self.client.get(reverse("page-search", kwargs={"language": "en"}))
self.assertEqual(response.status_code, 200)
data = response.json()
results = data["results"]

# Validate REST Pagination Attributes
self.assertIn("count", data)
self.assertIn("next", data)
self.assertIn("previous", data)
self.assertIn("results", data)
self.assertIsInstance(results, list)
self.assertEqual(data["count"], 0)
3 changes: 3 additions & 0 deletions tests/requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ drf-spectacular
# other requirements
coverage
tox

# avoid having to install cairo stack for testing
svglib!=1.6.0
5 changes: 5 additions & 0 deletions tests/requirements/dj52_cmsmain.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-r base.txt

Django>=5.2,<5.3
git+https://github.com/django-cms/django-cms.git@main

2 changes: 1 addition & 1 deletion tests/requirements/dj60_cms50.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-r base.txt

Django>=6.0a1,<6.1
django-cms>=5.0.0a1,<5.1
django-cms>=5.0,<5.1
Loading