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

Filter feed by hub slug, add a way to filter out journals from hubs #2127

Merged
merged 3 commits into from
Feb 25, 2025
Merged
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
2 changes: 1 addition & 1 deletion src/feed/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def test_following_feed_view(self):
def test_hub_filter(self):
"""Test filtering feed by hub"""
url = reverse("feed-list")
response = self.client.get(url, {"hub_id": self.hub.id})
response = self.client.get(url, {"hub_slug": self.hub.slug})

self.assertEqual(response.status_code, status.HTTP_200_OK)
# Should only see content from specified hub
Expand Down
15 changes: 11 additions & 4 deletions src/feed/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from django.contrib.contenttypes.models import ContentType
from django.db.models import F, Prefetch, Window
from django.db.models.functions import RowNumber
from rest_framework import viewsets
from rest_framework import status, viewsets
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response

from paper.related_models.paper_model import Paper
from reputation.related_models.bounty import Bounty
Expand Down Expand Up @@ -33,7 +34,7 @@
action = self.request.query_params.get("action")
content_type = self.request.query_params.get("content_type")
feed_view = self.request.query_params.get("feed_view", "latest")
hub_id = self.request.query_params.get("hub_id")
hub_slug = self.request.query_params.get("hub_slug")

queryset = (
FeedEntry.objects.all().select_related(
Expand Down Expand Up @@ -79,12 +80,18 @@
)

# Apply hub filter if hub_id is provided
if hub_id:
if hub_slug:
from hub.models import Hub

hub = Hub.objects.get(slug=hub_slug)
if not hub:
return Response(

Check warning on line 88 in src/feed/views.py

View check run for this annotation

Codecov / codecov/patch

src/feed/views.py#L88

Added line #L88 was not covered by tests
{"error": "Hub not found"}, status=status.HTTP_404_NOT_FOUND
)

hub_content_type = ContentType.objects.get_for_model(Hub)
queryset = queryset.filter(
parent_content_type=hub_content_type, parent_object_id=hub_id
parent_content_type=hub_content_type, parent_object_id=hub.id
)

# Apply additional filters.
Expand Down
21 changes: 21 additions & 0 deletions src/hub/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,24 @@ def get_invite_to_hub_response(self, user, hub, emails):
return get_authenticated_post_response(
user, url, data, headers={"HTTP_ORIGIN": "researchhub.com"}
)

def test_exclude_journals_parameter(self):
"""Test that exclude_journals parameter filters out journal hubs"""
# Create a journal hub
create_hub(name="Journal Hub", namespace="journal")

# Test with exclude_journals=true
response = get_get_response(self.base_url + "?exclude_journals=true")
results = response.data["results"]
self.assertEqual(len(results), 2) # includes self.hub and self.hub2 from setUp
hub_names = [h["name"] for h in results]
self.assertNotIn("Journal Hub", hub_names)

def test_include_journals_parameter(self):
"""Test that exclude_journals=false includes journal hubs"""

# Test with exclude_journals=false
response = get_get_response(self.base_url + "?exclude_journals=false")
self.assertEqual(
len(response.data["results"]), 2
) # includes self.hub and self.hub2 from setUp
9 changes: 9 additions & 0 deletions src/hub/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ class HubViewSet(viewsets.ModelViewSet, FollowViewActionMixin):
filterset_class = HubFilter
search_fields = "name"

def get_queryset(self):
queryset = super().get_queryset()
exclude_journals = (
self.request.query_params.get("exclude_journals", "").lower() == "true"
)
if exclude_journals:
queryset = queryset.exclude(namespace="journal")
return queryset

def get_serializer_context(self):
return {
**super().get_serializer_context(),
Expand Down
Loading