Source code for users.serializers

"""Serializers for the users app."""

from typing import Dict

from django.contrib.auth.models import User
from django.contrib.auth.validators import UnicodeUsernameValidator

from rest_framework.exceptions import ValidationError
from rest_framework.fields import (
    CharField, CurrentUserDefault, EmailField, HiddenField, URLField
)
from rest_framework.pagination import BasePagination
from rest_framework.relations import SlugRelatedField
from rest_framework.serializers import ModelSerializer

from reader.models import Series

from .models import Bookmark, UserProfile


[docs]class BookmarkPagination(BasePagination): """Fake pagination class to adapt the bookmarks list schema."""
[docs] def to_html(self) -> str: return ''
[docs] def get_paginated_response_schema(self, schema: Dict) -> Dict: return { 'type': 'object', 'properties': { 'rss': { 'type': 'string', 'format': 'uri' }, 'atom': { 'type': 'string', 'format': 'uri' }, 'bookmarks': schema } }
[docs]class BookmarkSerializer(ModelSerializer): """Serializer for bookmarks.""" series = SlugRelatedField( queryset=Series.objects.only('id', 'slug', 'title'), slug_field='slug', help_text='The slug of the series.' ) user = HiddenField(default=CurrentUserDefault())
[docs] def validate(self, attrs: Dict) -> Dict: if Bookmark.objects.filter(**attrs).exists(): raise ValidationError( {'error': 'This bookmark already exists.'} ) return attrs
[docs] class Meta: model = Bookmark fields = ('series', 'user')
[docs]class ProfileSerializer(ModelSerializer): """Serializer for user profiles.""" username = CharField( source='user.username', max_length=150, required=True, help_text='Your (unique) username.', validators=(UnicodeUsernameValidator(),), ) first_name = CharField( source='user.first_name', max_length=150, required=False, help_text='Your first name.' ) last_name = CharField( source='user.last_name', max_length=150, required=False, help_text='Your last name.' ) email = EmailField( source='user.email', max_length=254, required=True, help_text='Your e-mail address.' ) password = CharField( source='user.password', min_length=8, max_length=128, required=False, write_only=True, style={'input_type': 'password'}, help_text='You can set this if you want to change your password.' ) url = URLField( source='get_absolute_url', read_only=True, help_text='The absolute URL of your profile.' )
[docs] def validate_username(self, value: str) -> str: if not value: return '' users = User.objects.filter(username=value) if users.exclude(id=self.context['request'].user.id).exists(): from rest_framework.exceptions import ValidationError raise ValidationError('This username is already taken.') return value
[docs] class Meta: model = UserProfile fields = ( 'username', 'first_name', 'last_name', 'email', 'bio', 'avatar', 'password', 'url', ) extra_kwargs = { 'bio': { 'help_text': 'Some info about yourself.', 'label': None }, 'avatar': { 'help_text': 'Your avatar image. (<2MBs)', 'allow_null': True }, 'username': { 'pattern': '^[-a-zA-Z0-9@+_.]+$' } }
__all__ = ['BookmarkPagination', 'BookmarkSerializer', 'ProfileSerializer']