mirror of
https://github.com/sissbruecker/linkding
synced 2024-11-25 21:00:18 +00:00
3e4f08f51b
* feat: Implement UserProfile serializer and add API endpoint per #457 * chore: Document API addition * Address review comments --------- Co-authored-by: fkulla <mail@florian.direct>
109 lines
3.9 KiB
Python
109 lines
3.9 KiB
Python
from django.db.models import prefetch_related_objects
|
|
from rest_framework import serializers
|
|
from rest_framework.serializers import ListSerializer
|
|
|
|
from bookmarks.models import Bookmark, Tag, build_tag_string, UserProfile
|
|
from bookmarks.services.bookmarks import create_bookmark, update_bookmark
|
|
from bookmarks.services.tags import get_or_create_tag
|
|
|
|
|
|
class TagListField(serializers.ListField):
|
|
child = serializers.CharField()
|
|
|
|
|
|
class BookmarkListSerializer(ListSerializer):
|
|
def to_representation(self, data):
|
|
# Prefetch nested relations to avoid n+1 queries
|
|
prefetch_related_objects(data, 'tags')
|
|
|
|
return super().to_representation(data)
|
|
|
|
|
|
class BookmarkSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Bookmark
|
|
fields = [
|
|
'id',
|
|
'url',
|
|
'title',
|
|
'description',
|
|
'notes',
|
|
'website_title',
|
|
'website_description',
|
|
'is_archived',
|
|
'unread',
|
|
'shared',
|
|
'tag_names',
|
|
'date_added',
|
|
'date_modified'
|
|
]
|
|
read_only_fields = [
|
|
'website_title',
|
|
'website_description',
|
|
'date_added',
|
|
'date_modified'
|
|
]
|
|
list_serializer_class = BookmarkListSerializer
|
|
|
|
# Override optional char fields to provide default value
|
|
title = serializers.CharField(required=False, allow_blank=True, default='')
|
|
description = serializers.CharField(required=False, allow_blank=True, default='')
|
|
notes = serializers.CharField(required=False, allow_blank=True, default='')
|
|
is_archived = serializers.BooleanField(required=False, default=False)
|
|
unread = serializers.BooleanField(required=False, default=False)
|
|
shared = serializers.BooleanField(required=False, default=False)
|
|
# Override readonly tag_names property to allow passing a list of tag names to create/update
|
|
tag_names = TagListField(required=False, default=[])
|
|
|
|
def create(self, validated_data):
|
|
bookmark = Bookmark()
|
|
bookmark.url = validated_data['url']
|
|
bookmark.title = validated_data['title']
|
|
bookmark.description = validated_data['description']
|
|
bookmark.notes = validated_data['notes']
|
|
bookmark.is_archived = validated_data['is_archived']
|
|
bookmark.unread = validated_data['unread']
|
|
bookmark.shared = validated_data['shared']
|
|
tag_string = build_tag_string(validated_data['tag_names'])
|
|
return create_bookmark(bookmark, tag_string, self.context['user'])
|
|
|
|
def update(self, instance: Bookmark, validated_data):
|
|
# Update fields if they were provided in the payload
|
|
for key in ['url', 'title', 'description', 'notes', 'unread', 'shared']:
|
|
if key in validated_data:
|
|
setattr(instance, key, validated_data[key])
|
|
|
|
# Use tag string from payload, or use bookmark's current tags as fallback
|
|
tag_string = build_tag_string(instance.tag_names)
|
|
if 'tag_names' in validated_data:
|
|
tag_string = build_tag_string(validated_data['tag_names'])
|
|
|
|
return update_bookmark(instance, tag_string, self.context['user'])
|
|
|
|
|
|
class TagSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Tag
|
|
fields = ['id', 'name', 'date_added']
|
|
read_only_fields = ['date_added']
|
|
|
|
def create(self, validated_data):
|
|
return get_or_create_tag(validated_data['name'], self.context['user'])
|
|
|
|
|
|
class UserProfileSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = UserProfile
|
|
fields = [
|
|
"theme",
|
|
"bookmark_date_display",
|
|
"bookmark_link_target",
|
|
"web_archive_integration",
|
|
"tag_search",
|
|
"enable_sharing",
|
|
"enable_public_sharing",
|
|
"enable_favicons",
|
|
"display_url",
|
|
"permanent_notes",
|
|
"search_preferences",
|
|
]
|