ptitlutins-backend/voyage/serializers.py
2025-09-14 04:54:02 +02:00

130 lines
4.8 KiB
Python

from rest_framework import serializers
from .models import Voyage, VoyagePermission, VoyageLink, Location, Event, Need, Trip
from django.contrib.auth.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'username']
extra_kwargs = {
'username': {'required': False}
}
class VoyagePermissionSerializer(serializers.ModelSerializer):
class Meta:
model = VoyagePermission
fields = ['id', 'view', 'change', 'voyage', 'user']
class VoyageSerializer(serializers.ModelSerializer):
collaborator_permissions = VoyagePermissionSerializer(many=True, required=False)
collaborators = serializers.PrimaryKeyRelatedField(many=True, queryset=User.objects.all(), required=False)
class Meta:
model = Voyage
fields = ['id', 'title', 'description', 'creator', 'collaborators', 'collaborator_permissions', 'created_at']
read_only_fields = ['creator', 'created_at']
class VoyageLinkSerializer(serializers.ModelSerializer):
voyage = VoyageSerializer(required=False)
voyage_id = serializers.CharField(required=False)
permission = VoyagePermissionSerializer()
class Meta:
model = VoyageLink
fields = ['id', 'voyage', 'permission', 'voyage_id']
depth = 1
def create(self, validated_data):
extra_data = {}
if voyage_id := validated_data.get('voyage_id'):
voyage = Voyage.objects.get(id=voyage_id)
permission_data = validated_data.pop('permission')
elif "voyage" in validated_data:
voyage_data = validated_data.pop('voyage')
creator = validated_data.get('voyage_creator', None)
voyage = Voyage.objects.create(title=voyage_data.get('title'), description=voyage_data.get('description'), creator=creator)
extra_data['primary'] = True
if creator:
permission_data = {}
else: # Grant all rights for anonymous user
permission_data = {
'view': True,
'change': True,
}
else:
raise serializers.ValidationError("Should include voyage or voyage_id")
permission = VoyagePermission.objects.create(**permission_data)
return VoyageLink.objects.create(voyage=voyage, permission=permission, **extra_data)
def update(self, instance, validated_data):
voyage_data = validated_data.pop('voyage')
voyage = instance.voyage
# Update voyage collaborator permissions
collaborator_permissions_data = voyage_data.get('collaborator_permissions', [])
for collaborator_permission_data in collaborator_permissions_data:
try:
collaborator_permission = voyage.collaborator_permissions.get(user=collaborator_permission_data['user'])
collaborator_permission.update_permission(collaborator_permission_data)
except VoyagePermission.DoesNotExist:
raise serializers.ValidationError("User in permission is not a collaborator")
# Update voyage collaborators
collaborators_data = voyage_data.get('collaborators')
if collaborators_data is not None:
voyage.collaborators.set(collaborators_data)
# Update voyage title & description
if title := voyage_data.get('title'):
voyage.title = title
if description := voyage_data.get('description'):
voyage.description = description
voyage.save()
# Update permission
permission_data = validated_data.get('permission', {})
if permission_data:
permission = instance.permission
permission.update_permission(permission_data)
return instance
class LocationSerializer(serializers.ModelSerializer):
class Meta:
model = Location
fields = ['id', 'name', 'postal_address', 'latitude', 'longitude', 'osm_id']
class EventSerializer(serializers.ModelSerializer):
location = LocationSerializer(read_only=True)
location_id = serializers.PrimaryKeyRelatedField(
queryset=Location.objects.all(), source="location", write_only=True, required=False
)
parent = serializers.PrimaryKeyRelatedField(queryset=Event.objects.all(), allow_null=True)
participants = UserSerializer(many=True, read_only=True)
class Meta:
model = Event
fields = ['id', 'title', 'start_date', 'end_date', 'location', 'location_id', 'note', 'parent', 'participants']
class NeedSerializer(serializers.ModelSerializer):
class Meta:
model = Need
fields = ['id', 'item', 'proposed_by', 'event']
class TripSerializer(serializers.ModelSerializer):
class Meta:
model = Trip
fields = ['id', 'event_start', 'event_end', 'mode', 'itinerary']