updated new username feature to api app; restructured api urlpatterns for more sustainable pahts
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Disco DeDisco
2026-03-01 21:44:30 -05:00
parent 4aa63c74e2
commit 143e81fc41
5 changed files with 59 additions and 6 deletions

View File

@@ -1,5 +1,7 @@
from rest_framework import serializers from rest_framework import serializers
from apps.dashboard.models import Item, List from apps.dashboard.models import Item, List
from apps.lyric.models import User
class ItemSerializer(serializers.ModelSerializer): class ItemSerializer(serializers.ModelSerializer):
@@ -15,3 +17,8 @@ class ListSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = List model = List
fields = ["id", "name", "url", "items"] fields = ["id", "name", "url", "items"]
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ["id", "username"]

View File

@@ -60,3 +60,35 @@ class ListsAPITest(BaseAPITest):
self.assertEqual(List.objects.count(), 1) self.assertEqual(List.objects.count(), 1)
self.assertEqual(List.objects.first().owner, self.user) self.assertEqual(List.objects.first().owner, self.user)
self.assertEqual(Item.objects.first().text, "first item") self.assertEqual(Item.objects.first().text, "first item")
class UserSearchAPITest(BaseAPITest):
def test_returns_users_matching_username(self):
disco = User.objects.create_user("disco@example.com")
disco.username = "discoman"
disco.searchable = True
disco.save()
response = self.client.get("/api/users/?q=disc")
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
self.assertEqual(response.data[0]["username"], "discoman")
def test_non_searchable_users_are_excluded(self):
alice = User.objects.create_user("alice@example.com")
alice.username = "princessAli"
alice.save() # searchable defaults to False
response = self.client.get("/api/users/?q=prin")
self.assertEqual(response.data, [])
def test_response_does_not_include_email(self):
alice = User.objects.create_user("alice@example.com")
alice.username = "princessAli"
alice.searchable = True
alice.save()
response = self.client.get("/api/users/?q=prin")
self.assertNotIn("email", response.data[0])

View File

@@ -4,8 +4,9 @@ from . import views
urlpatterns = [ urlpatterns = [
path('', views.ListsAPI.as_view(), name='api_lists'), path('lists/', views.ListsAPI.as_view(), name='api_lists'),
path('<uuid:list_id>/', views.ListDetailAPI.as_view(), name='api_list_detail'), path('lists/<uuid:list_id>/', views.ListDetailAPI.as_view(), name='api_list_detail'),
path('<uuid:list_id>/items/', views.ListItemsAPI.as_view(), name='api_list_items'), path('lists/<uuid:list_id>/items/', views.ListItemsAPI.as_view(), name='api_list_items'),
path('users/', views.UserSearchAPI.as_view(), name='api_users'),
] ]

View File

@@ -2,8 +2,9 @@ from django.shortcuts import get_object_or_404
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from apps.api.serializers import ItemSerializer, ListSerializer, UserSerializer
from apps.dashboard.models import Item, List from apps.dashboard.models import Item, List
from apps.api.serializers import ItemSerializer, ListSerializer from apps.lyric.models import User
class ListDetailAPI(APIView): class ListDetailAPI(APIView):
@@ -32,3 +33,13 @@ class ListsAPI(APIView):
item = Item.objects.create(text=request.data.get("text", ""), list=list_) item = Item.objects.create(text=request.data.get("text", ""), list=list_)
serializer = ListSerializer(list_) serializer = ListSerializer(list_)
return Response(serializer.data, status=201) return Response(serializer.data, status=201)
class UserSearchAPI(APIView):
def get(self, request):
q = request.query_params.get("q", "")
users = User.objects.filter(
username__icontains=q,
searchable=True,
)
serializer = UserSerializer(users, many=True)
return Response(serializer.data)

View File

@@ -1,14 +1,16 @@
from django.contrib import admin from django.contrib import admin
from django.http import HttpResponse from django.http import HttpResponse
from django.urls import include, path from django.urls import include, path
from apps.dashboard import views as dash_views from apps.dashboard import views as dash_views
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('', dash_views.home_page, name='home'), path('', dash_views.home_page, name='home'),
path('api/', include('apps.api.urls')),
path('dashboard/', include('apps.dashboard.urls')), path('dashboard/', include('apps.dashboard.urls')),
path('lyric/', include('apps.lyric.urls')), path('lyric/', include('apps.lyric.urls')),
path('api/lists/', include('apps.api.urls')),
] ]
# Please remove the following urlpattern # Please remove the following urlpattern