Add REST API for bookmark bundles (#1100)

* Add bundles API

* Add docs
This commit is contained in:
Sascha Ißbrücker
2025-06-19 22:19:29 +02:00
committed by GitHub
parent 20e31397cc
commit 549554cc17
5 changed files with 487 additions and 3 deletions

View File

@@ -16,8 +16,16 @@ from bookmarks.api.serializers import (
BookmarkAssetSerializer,
TagSerializer,
UserProfileSerializer,
BookmarkBundleSerializer,
)
from bookmarks.models import (
Bookmark,
BookmarkAsset,
BookmarkSearch,
Tag,
User,
BookmarkBundle,
)
from bookmarks.models import Bookmark, BookmarkAsset, BookmarkSearch, Tag, User
from bookmarks.services import assets, bookmarks, auto_tagging, website_loader
from bookmarks.type_defs import HttpRequest
from bookmarks.views import access
@@ -264,6 +272,25 @@ class UserViewSet(viewsets.GenericViewSet):
return Response(UserProfileSerializer(request.user.profile).data)
class BookmarkBundleViewSet(
viewsets.GenericViewSet,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
):
request: HttpRequest
serializer_class = BookmarkBundleSerializer
def get_queryset(self):
user = self.request.user
return BookmarkBundle.objects.filter(owner=user).order_by("order")
def get_serializer_context(self):
return {"user": self.request.user}
# DRF routers do not support nested view sets such as /bookmarks/<id>/assets/<id>/
# Instead create separate routers for each view set and manually register them in urls.py
# The default router is only used to allow reversing a URL for the API root
@@ -278,5 +305,8 @@ tag_router.register("", TagViewSet, basename="tag")
user_router = SimpleRouter()
user_router.register("", UserViewSet, basename="user")
bundle_router = SimpleRouter()
bundle_router.register("", BookmarkBundleViewSet, basename="bundle")
bookmark_asset_router = SimpleRouter()
bookmark_asset_router.register("", BookmarkAssetViewSet, basename="bookmark_asset")

View File

@@ -1,9 +1,16 @@
from django.db.models import prefetch_related_objects
from django.db.models import Max, prefetch_related_objects
from django.templatetags.static import static
from rest_framework import serializers
from rest_framework.serializers import ListSerializer
from bookmarks.models import Bookmark, BookmarkAsset, Tag, build_tag_string, UserProfile
from bookmarks.models import (
Bookmark,
BookmarkAsset,
Tag,
build_tag_string,
UserProfile,
BookmarkBundle,
)
from bookmarks.services import bookmarks
from bookmarks.services.tags import get_or_create_tag
from bookmarks.services.wayback import generate_fallback_webarchive_url
@@ -27,6 +34,40 @@ class EmtpyField(serializers.ReadOnlyField):
return None
class BookmarkBundleSerializer(serializers.ModelSerializer):
class Meta:
model = BookmarkBundle
fields = [
"id",
"name",
"search",
"any_tags",
"all_tags",
"excluded_tags",
"order",
"date_created",
"date_modified",
]
read_only_fields = [
"id",
"date_created",
"date_modified",
]
def create(self, validated_data):
# Set owner to the authenticated user
validated_data["owner"] = self.context["user"]
# Set order to the next available position if not provided
if "order" not in validated_data:
max_order = BookmarkBundle.objects.filter(
owner=self.context["user"]
).aggregate(Max("order", default=-1))["order__max"]
validated_data["order"] = max_order + 1
return super().create(validated_data)
class BookmarkSerializer(serializers.ModelSerializer):
class Meta:
model = Bookmark