Files
aurora-moments/api/apps/accounts/serializers.py
T
KrisandClaude Sonnet 5 4877e0a779 Initial commit: Aurora Moments self-hosted photo/video sharing platform
Django/DRF + PostgreSQL/Redis/Celery backend with accounts, library,
moments, and notifications apps; React/TypeScript/Vite frontend with
Instagram-style sidebar nav, feed, profiles, nested comment replies,
notifications, and photo/video upload with ffmpeg-generated posters.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-10 10:28:53 -05:00

92 lines
3.3 KiB
Python

from django.contrib.auth import password_validation
from rest_framework import serializers
from .models import Follow, User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ["id", "username", "display_name", "bio", "avatar", "is_private", "date_joined"]
read_only_fields = ["id", "date_joined"]
class ProfileSerializer(UserSerializer):
"""UserSerializer plus the counts/relationship state a profile page
needs. Kept separate from UserSerializer (used for owner/author fields
all over the feed) so those hot paths don't pay for two extra COUNT
queries per embedded user."""
follower_count = serializers.SerializerMethodField()
following_count = serializers.SerializerMethodField()
viewer_follow_id = serializers.SerializerMethodField()
viewer_follow_status = serializers.SerializerMethodField()
class Meta(UserSerializer.Meta):
fields = UserSerializer.Meta.fields + [
"follower_count", "following_count", "viewer_follow_id", "viewer_follow_status",
]
def _viewer_follow(self, obj):
request = self.context.get("request")
if not request or not request.user.is_authenticated or request.user.id == obj.id:
return None
if not hasattr(obj, "_viewer_follow_cache"):
obj._viewer_follow_cache = Follow.objects.filter(follower=request.user, following=obj).first()
return obj._viewer_follow_cache
def get_follower_count(self, obj):
return obj.follower_edges.filter(status=Follow.Status.ACCEPTED).count()
def get_following_count(self, obj):
return obj.following_edges.filter(status=Follow.Status.ACCEPTED).count()
def get_viewer_follow_id(self, obj):
follow = self._viewer_follow(obj)
return follow.id if follow else None
def get_viewer_follow_status(self, obj):
follow = self._viewer_follow(obj)
return follow.status if follow else None
class RegisterSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
class Meta:
model = User
fields = ["id", "email", "username", "password", "display_name"]
def validate_password(self, value):
password_validation.validate_password(value)
return value
def create(self, validated_data):
password = validated_data.pop("password")
user = User(**validated_data)
user.set_password(password)
user.save()
return user
class FollowSerializer(serializers.ModelSerializer):
follower = UserSerializer(read_only=True)
following = UserSerializer(read_only=True)
following_id = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all(), source="following", write_only=True
)
class Meta:
model = Follow
fields = ["id", "follower", "following", "following_id", "status", "created_at"]
read_only_fields = ["id", "follower", "status", "created_at"]
def create(self, validated_data):
follower = self.context["request"].user
following = validated_data["following"]
status = Follow.Status.PENDING if following.is_private else Follow.Status.ACCEPTED
follow, _ = Follow.objects.get_or_create(
follower=follower, following=following, defaults={"status": status}
)
return follow