2024-10-31 09:51:04 -04:00
from django . utils import timezone
2024-07-08 11:44:39 -04:00
import os
2025-07-10 12:12:03 -04:00
from . models import Location , ContentImage , ChecklistItem , Collection , Note , Transportation , Checklist , Visit , Category , ContentAttachment , Lodging
2024-07-08 11:44:39 -04:00
from rest_framework import serializers
2024-11-17 16:34:46 -05:00
from main . utils import CustomModelSerializer
2025-02-01 15:10:25 -05:00
from users . serializers import CustomUserDetailsSerializer
2025-05-23 17:22:28 -04:00
from worldtravel . serializers import CountrySerializer , RegionSerializer , CitySerializer
2025-05-30 12:33:30 -04:00
from geopy . distance import geodesic
2025-06-02 21:25:07 -04:00
from integrations . models import ImmichIntegration
2024-07-08 11:44:39 -04:00
2024-11-17 16:34:46 -05:00
2025-07-10 12:12:03 -04:00
class ContentImageSerializer ( CustomModelSerializer ) :
2024-08-15 19:36:42 -04:00
class Meta :
2025-07-10 12:12:03 -04:00
model = ContentImage
2025-07-12 09:20:23 -04:00
fields = [ ' id ' , ' image ' , ' is_primary ' , ' user ' , ' immich_id ' ]
2025-07-09 23:08:54 -04:00
read_only_fields = [ ' id ' , ' user ' ]
2024-08-15 19:36:42 -04:00
2024-08-18 08:43:49 -04:00
def to_representation ( self , instance ) :
2025-06-03 17:16:28 -04:00
# If immich_id is set, check for user integration once
integration = None
2025-06-01 19:55:12 -04:00
if instance . immich_id :
2025-07-09 23:08:54 -04:00
integration = ImmichIntegration . objects . filter ( user = instance . user ) . first ( )
2025-06-03 17:16:28 -04:00
if not integration :
return None # Skip if Immich image but no integration
# Base representation
representation = super ( ) . to_representation ( instance )
# Prepare public URL once
public_url = os . environ . get ( ' PUBLIC_URL ' , ' http://127.0.0.1:8000 ' ) . rstrip ( ' / ' ) . replace ( " ' " , " " )
if instance . immich_id :
# Use Immich integration URL
representation [ ' image ' ] = f " { public_url } /api/integrations/immich/ { integration . id } /get/ { instance . immich_id } "
elif instance . image :
# Use local image URL
representation [ ' image ' ] = f " { public_url } /media/ { instance . image . name } "
2025-06-02 21:25:07 -04:00
2024-08-15 19:36:42 -04:00
return representation
2024-10-07 19:51:45 -04:00
2025-01-19 00:05:08 -05:00
class AttachmentSerializer ( CustomModelSerializer ) :
extension = serializers . SerializerMethodField ( )
class Meta :
2025-07-10 12:12:03 -04:00
model = ContentAttachment
2025-07-12 09:20:23 -04:00
fields = [ ' id ' , ' file ' , ' extension ' , ' name ' , ' user ' ]
2025-07-09 23:08:54 -04:00
read_only_fields = [ ' id ' , ' user ' ]
2025-01-19 00:05:08 -05:00
def get_extension ( self , obj ) :
return obj . file . name . split ( ' . ' ) [ - 1 ]
def to_representation ( self , instance ) :
representation = super ( ) . to_representation ( instance )
if instance . file :
public_url = os . environ . get ( ' PUBLIC_URL ' , ' http://127.0.0.1:8000 ' ) . rstrip ( ' / ' )
#print(public_url)
# remove any ' from the url
public_url = public_url . replace ( " ' " , " " )
representation [ ' file ' ] = f " { public_url } /media/ { instance . file . name } "
return representation
2024-11-23 13:42:41 -05:00
class CategorySerializer ( serializers . ModelSerializer ) :
2025-07-09 23:08:54 -04:00
num_locations = serializers . SerializerMethodField ( )
2024-11-14 09:37:35 -05:00
class Meta :
model = Category
2025-07-09 23:08:54 -04:00
fields = [ ' id ' , ' name ' , ' display_name ' , ' icon ' , ' num_locations ' ]
read_only_fields = [ ' id ' , ' num_locations ' ]
2024-11-14 09:37:35 -05:00
def validate_name ( self , value ) :
2024-11-23 13:42:41 -05:00
return value . lower ( )
def create ( self , validated_data ) :
user = self . context [ ' request ' ] . user
validated_data [ ' name ' ] = validated_data [ ' name ' ] . lower ( )
2025-07-09 23:08:54 -04:00
return Category . objects . create ( user = user , * * validated_data )
2024-11-23 13:42:41 -05:00
def update ( self , instance , validated_data ) :
for attr , value in validated_data . items ( ) :
setattr ( instance , attr , value )
if ' name ' in validated_data :
instance . name = validated_data [ ' name ' ] . lower ( )
instance . save ( )
return instance
2024-11-14 09:37:35 -05:00
2025-07-09 23:08:54 -04:00
def get_num_locations ( self , obj ) :
return Location . objects . filter ( category = obj , user = obj . user ) . count ( )
2024-11-17 16:34:46 -05:00
2024-11-22 17:03:02 -05:00
class VisitSerializer ( serializers . ModelSerializer ) :
2024-10-31 09:51:04 -04:00
2024-10-07 19:51:45 -04:00
class Meta :
model = Visit
2025-05-10 11:59:56 -04:00
fields = [ ' id ' , ' start_date ' , ' end_date ' , ' timezone ' , ' notes ' ]
2024-10-07 19:51:45 -04:00
read_only_fields = [ ' id ' ]
2024-10-31 09:51:04 -04:00
2025-07-09 23:08:54 -04:00
class LocationSerializer ( CustomModelSerializer ) :
2025-06-03 17:16:28 -04:00
images = serializers . SerializerMethodField ( )
2024-11-23 13:42:41 -05:00
visits = VisitSerializer ( many = True , read_only = False , required = False )
2025-01-19 00:05:08 -05:00
attachments = AttachmentSerializer ( many = True , read_only = True )
2024-11-23 13:42:41 -05:00
category = CategorySerializer ( read_only = False , required = False )
2024-10-31 09:51:04 -04:00
is_visited = serializers . SerializerMethodField ( )
2025-05-23 17:22:28 -04:00
country = CountrySerializer ( read_only = True )
region = RegionSerializer ( read_only = True )
city = CitySerializer ( read_only = True )
2025-06-12 15:54:01 -04:00
collections = serializers . PrimaryKeyRelatedField (
many = True ,
queryset = Collection . objects . all ( ) ,
required = False
)
2024-11-22 17:03:02 -05:00
2024-07-08 11:44:39 -04:00
class Meta :
2025-07-09 23:08:54 -04:00
model = Location
2024-11-22 17:03:02 -05:00
fields = [
2025-07-09 23:08:54 -04:00
' id ' , ' name ' , ' description ' , ' rating ' , ' tags ' , ' location ' ,
2025-06-12 15:54:01 -04:00
' is_public ' , ' collections ' , ' created_at ' , ' updated_at ' , ' images ' , ' link ' , ' longitude ' ,
2025-05-22 20:05:13 -04:00
' latitude ' , ' visits ' , ' is_visited ' , ' category ' , ' attachments ' , ' user ' , ' city ' , ' country ' , ' region '
2024-11-22 17:03:02 -05:00
]
2025-07-09 23:08:54 -04:00
read_only_fields = [ ' id ' , ' created_at ' , ' updated_at ' , ' user ' , ' is_visited ' ]
# Makes it so the whole user object is returned in the serializer instead of just the user uuid
def to_representation ( self , instance ) :
representation = super ( ) . to_representation ( instance )
representation [ ' user ' ] = CustomUserDetailsSerializer ( instance . user , context = self . context ) . data
return representation
2024-10-31 09:51:04 -04:00
2025-06-03 17:16:28 -04:00
def get_images ( self , obj ) :
2025-07-10 12:12:03 -04:00
serializer = ContentImageSerializer ( obj . images . all ( ) , many = True , context = self . context )
2025-06-03 17:16:28 -04:00
# Filter out None values from the serialized data
return [ image for image in serializer . data if image is not None ]
2025-06-12 15:54:01 -04:00
def validate_collections ( self , collections ) :
2025-07-12 09:20:23 -04:00
""" Validate that collections are compatible with the location being created/updated """
2025-07-14 18:57:39 -04:00
2025-06-12 15:54:01 -04:00
if not collections :
return collections
user = self . context [ ' request ' ] . user
2025-07-12 09:20:23 -04:00
# Get the location being updated (if this is an update operation)
location_owner = getattr ( self . instance , ' user ' , None ) if self . instance else user
2025-07-14 18:57:39 -04:00
# For updates, we need to check if collections are being added or removed
current_collections = set ( self . instance . collections . all ( ) ) if self . instance else set ( )
new_collections_set = set ( collections )
collections_to_add = new_collections_set - current_collections
collections_to_remove = current_collections - new_collections_set
# Validate collections being added
for collection in collections_to_add :
2025-07-12 09:20:23 -04:00
# Check if user has permission to use this collection
2025-07-14 18:57:39 -04:00
user_has_shared_access = collection . shared_with . filter ( id = user . id ) . exists ( )
if collection . user != user and not user_has_shared_access :
2025-06-12 15:54:01 -04:00
raise serializers . ValidationError (
2025-07-14 18:57:39 -04:00
f " The requested collection does not belong to the current user. "
2025-06-12 15:54:01 -04:00
)
2025-07-12 09:20:23 -04:00
2025-07-14 18:57:39 -04:00
# Check location owner compatibility - both directions
if collection . user != location_owner :
# If user owns the collection but not the location, location owner must have shared access
if collection . user == user :
location_owner_has_shared_access = collection . shared_with . filter ( id = location_owner . id ) . exists ( ) if location_owner else False
if not location_owner_has_shared_access :
raise serializers . ValidationError (
f " Locations must be associated with collections owned by the same user or shared collections. Collection owner: { collection . user . username } Location owner: { location_owner . username if location_owner else ' None ' } "
)
# If using someone else's collection, location owner must have shared access
else :
location_owner_has_shared_access = collection . shared_with . filter ( id = location_owner . id ) . exists ( ) if location_owner else False
if not location_owner_has_shared_access :
raise serializers . ValidationError (
" Location cannot be added to collection unless the location owner has shared access to the collection. "
)
# Validate collections being removed - allow if user owns the collection OR owns the location
for collection in collections_to_remove :
user_owns_collection = collection . user == user
user_owns_location = location_owner == user if location_owner else False
user_has_shared_access = collection . shared_with . filter ( id = user . id ) . exists ( )
if not ( user_owns_collection or user_owns_location or user_has_shared_access ) :
2025-07-12 09:20:23 -04:00
raise serializers . ValidationError (
2025-07-14 18:57:39 -04:00
" You don ' t have permission to remove this location from one of the collections it ' s linked to. "
2025-07-12 09:20:23 -04:00
)
2025-06-12 15:54:01 -04:00
return collections
2024-11-23 13:42:41 -05:00
def validate_category ( self , category_data ) :
if isinstance ( category_data , Category ) :
return category_data
if category_data :
user = self . context [ ' request ' ] . user
name = category_data . get ( ' name ' , ' ' ) . lower ( )
2025-07-09 23:08:54 -04:00
existing_category = Category . objects . filter ( user = user , name = name ) . first ( )
2024-11-23 13:42:41 -05:00
if existing_category :
return existing_category
category_data [ ' name ' ] = name
return category_data
2025-05-22 20:13:36 -04:00
2024-11-23 13:42:41 -05:00
def get_or_create_category ( self , category_data ) :
user = self . context [ ' request ' ] . user
if isinstance ( category_data , Category ) :
return category_data
if isinstance ( category_data , dict ) :
name = category_data . get ( ' name ' , ' ' ) . lower ( )
display_name = category_data . get ( ' display_name ' , name )
2025-06-12 15:54:01 -04:00
icon = category_data . get ( ' icon ' , ' 🌍 ' )
2024-11-23 13:42:41 -05:00
else :
name = category_data . name . lower ( )
display_name = category_data . display_name
icon = category_data . icon
2024-11-22 17:03:02 -05:00
2024-11-23 13:42:41 -05:00
category , created = Category . objects . get_or_create (
2025-07-09 23:08:54 -04:00
user = user ,
2024-11-23 13:42:41 -05:00
name = name ,
defaults = {
' display_name ' : display_name ,
' icon ' : icon
}
)
2024-11-22 17:03:02 -05:00
return category
2025-02-01 15:10:25 -05:00
2024-10-31 09:51:04 -04:00
def get_is_visited ( self , obj ) :
2025-05-22 21:13:31 -04:00
return obj . is_visited_status ( )
2024-07-08 11:44:39 -04:00
2024-09-22 00:07:45 -04:00
def create ( self , validated_data ) :
2025-01-03 09:53:23 -05:00
visits_data = validated_data . pop ( ' visits ' , None )
2024-11-23 13:42:41 -05:00
category_data = validated_data . pop ( ' category ' , None )
2025-06-12 15:54:01 -04:00
collections_data = validated_data . pop ( ' collections ' , [ ] )
2024-11-26 17:39:10 -05:00
print ( category_data )
2025-07-09 23:08:54 -04:00
location = Location . objects . create ( * * validated_data )
2025-06-12 15:54:01 -04:00
# Handle visits
2024-09-22 00:07:45 -04:00
for visit_data in visits_data :
2025-07-09 23:08:54 -04:00
Visit . objects . create ( location = location , * * visit_data )
2024-11-23 13:42:41 -05:00
2025-06-12 15:54:01 -04:00
# Handle category
2024-11-23 13:42:41 -05:00
if category_data :
category = self . get_or_create_category ( category_data )
2025-07-09 23:08:54 -04:00
location . category = category
2025-06-12 15:54:01 -04:00
2025-07-09 23:08:54 -04:00
# Handle collections - set after location is saved
2025-06-12 15:54:01 -04:00
if collections_data :
2025-07-09 23:08:54 -04:00
location . collections . set ( collections_data )
2025-05-22 21:13:31 -04:00
2025-07-09 23:08:54 -04:00
location . save ( )
2024-11-23 13:42:41 -05:00
2025-07-09 23:08:54 -04:00
return location
2024-11-22 17:03:02 -05:00
2024-09-22 00:07:45 -04:00
def update ( self , instance , validated_data ) :
2025-01-03 09:53:23 -05:00
has_visits = ' visits ' in validated_data
2024-09-22 00:07:45 -04:00
visits_data = validated_data . pop ( ' visits ' , [ ] )
2024-11-23 13:42:41 -05:00
category_data = validated_data . pop ( ' category ' , None )
2024-11-22 17:03:02 -05:00
2025-06-12 15:54:01 -04:00
collections_data = validated_data . pop ( ' collections ' , None )
# Update regular fields
2024-09-30 18:03:10 -04:00
for attr , value in validated_data . items ( ) :
setattr ( instance , attr , value )
2024-11-23 13:42:41 -05:00
2025-07-09 23:08:54 -04:00
# Handle category - ONLY allow the location owner to change categories
2025-06-12 15:54:01 -04:00
user = self . context [ ' request ' ] . user
2025-07-09 23:08:54 -04:00
if category_data and instance . user == user :
2025-06-12 15:54:01 -04:00
# Only the owner can set categories
2024-11-23 13:42:41 -05:00
category = self . get_or_create_category ( category_data )
instance . category = category
2025-06-12 15:54:01 -04:00
# If not the owner, ignore category changes
# Handle collections - only update if collections were provided
if collections_data is not None :
instance . collections . set ( collections_data )
2024-11-22 17:03:02 -05:00
2025-06-12 15:54:01 -04:00
# Handle visits
2025-01-03 09:53:23 -05:00
if has_visits :
current_visits = instance . visits . all ( )
current_visit_ids = set ( current_visits . values_list ( ' id ' , flat = True ) )
updated_visit_ids = set ( )
for visit_data in visits_data :
visit_id = visit_data . get ( ' id ' )
if visit_id and visit_id in current_visit_ids :
visit = current_visits . get ( id = visit_id )
for attr , value in visit_data . items ( ) :
setattr ( visit , attr , value )
visit . save ( )
updated_visit_ids . add ( visit_id )
else :
2025-07-09 23:08:54 -04:00
new_visit = Visit . objects . create ( location = instance , * * visit_data )
2025-01-03 09:53:23 -05:00
updated_visit_ids . add ( new_visit . id )
visits_to_delete = current_visit_ids - updated_visit_ids
instance . visits . filter ( id__in = visits_to_delete ) . delete ( )
2024-11-22 17:03:02 -05:00
2025-07-09 23:08:54 -04:00
# call save on the location to update the updated_at field and trigger any geocoding
2025-05-22 21:13:31 -04:00
instance . save ( )
2024-09-22 00:07:45 -04:00
return instance
2024-11-22 17:03:02 -05:00
2024-11-17 16:34:46 -05:00
class TransportationSerializer ( CustomModelSerializer ) :
2025-05-30 12:33:30 -04:00
distance = serializers . SerializerMethodField ( )
2025-07-14 18:57:39 -04:00
images = serializers . SerializerMethodField ( )
2024-07-27 19:04:55 -04:00
class Meta :
model = Transportation
fields = [
2025-07-09 23:08:54 -04:00
' id ' , ' user ' , ' type ' , ' name ' , ' description ' , ' rating ' ,
2024-07-27 19:04:55 -04:00
' link ' , ' date ' , ' flight_number ' , ' from_location ' , ' to_location ' ,
2025-05-30 12:33:30 -04:00
' is_public ' , ' collection ' , ' created_at ' , ' updated_at ' , ' end_date ' ,
' origin_latitude ' , ' origin_longitude ' , ' destination_latitude ' , ' destination_longitude ' ,
2025-07-14 18:57:39 -04:00
' start_timezone ' , ' end_timezone ' , ' distance ' , ' images '
2024-07-27 19:04:55 -04:00
]
2025-07-09 23:08:54 -04:00
read_only_fields = [ ' id ' , ' created_at ' , ' updated_at ' , ' user ' , ' distance ' ]
2025-05-30 12:33:30 -04:00
2025-07-14 18:57:39 -04:00
def get_images ( self , obj ) :
serializer = ContentImageSerializer ( obj . images . all ( ) , many = True , context = self . context )
# Filter out None values from the serialized data
return [ image for image in serializer . data if image is not None ]
2025-05-30 12:33:30 -04:00
def get_distance ( self , obj ) :
if (
obj . origin_latitude and obj . origin_longitude and
obj . destination_latitude and obj . destination_longitude
) :
try :
origin = ( float ( obj . origin_latitude ) , float ( obj . origin_longitude ) )
destination = ( float ( obj . destination_latitude ) , float ( obj . destination_longitude ) )
return round ( geodesic ( origin , destination ) . km , 2 )
except ValueError :
return None
return None
2024-07-27 19:04:55 -04:00
2025-02-08 16:10:01 -05:00
class LodgingSerializer ( CustomModelSerializer ) :
2025-07-14 18:57:39 -04:00
images = serializers . SerializerMethodField ( )
2025-02-05 19:38:04 -05:00
class Meta :
2025-02-08 16:10:01 -05:00
model = Lodging
2025-02-05 19:38:04 -05:00
fields = [
2025-07-09 23:08:54 -04:00
' id ' , ' user ' , ' name ' , ' description ' , ' rating ' , ' link ' , ' check_in ' , ' check_out ' ,
2025-07-14 18:57:39 -04:00
' reservation_number ' , ' price ' , ' latitude ' , ' longitude ' , ' location ' , ' is_public ' ,
' collection ' , ' created_at ' , ' updated_at ' , ' type ' , ' timezone ' , ' images '
2025-02-05 19:38:04 -05:00
]
2025-07-09 23:08:54 -04:00
read_only_fields = [ ' id ' , ' created_at ' , ' updated_at ' , ' user ' ]
2025-02-05 19:38:04 -05:00
2025-07-14 18:57:39 -04:00
def get_images ( self , obj ) :
serializer = ContentImageSerializer ( obj . images . all ( ) , many = True , context = self . context )
# Filter out None values from the serialized data
return [ image for image in serializer . data if image is not None ]
2024-11-17 16:34:46 -05:00
class NoteSerializer ( CustomModelSerializer ) :
2024-08-03 21:09:49 -04:00
class Meta :
model = Note
fields = [
2025-07-09 23:08:54 -04:00
' id ' , ' user ' , ' name ' , ' content ' , ' date ' , ' links ' ,
2024-08-03 21:09:49 -04:00
' is_public ' , ' collection ' , ' created_at ' , ' updated_at '
]
2025-07-09 23:08:54 -04:00
read_only_fields = [ ' id ' , ' created_at ' , ' updated_at ' , ' user ' ]
2024-07-27 19:22:01 -04:00
2024-11-17 16:34:46 -05:00
class ChecklistItemSerializer ( CustomModelSerializer ) :
2024-08-05 16:09:57 -04:00
class Meta :
model = ChecklistItem
fields = [
2025-07-09 23:08:54 -04:00
' id ' , ' user ' , ' name ' , ' is_checked ' , ' checklist ' , ' created_at ' , ' updated_at '
2024-08-05 16:09:57 -04:00
]
2025-07-09 23:08:54 -04:00
read_only_fields = [ ' id ' , ' created_at ' , ' updated_at ' , ' user ' , ' checklist ' ]
2024-10-07 19:51:45 -04:00
2024-11-17 16:34:46 -05:00
class ChecklistSerializer ( CustomModelSerializer ) :
2024-08-05 21:36:38 -04:00
items = ChecklistItemSerializer ( many = True , source = ' checklistitem_set ' )
2025-06-08 13:15:43 -04:00
2024-08-05 16:09:57 -04:00
class Meta :
model = Checklist
fields = [
2025-07-09 23:08:54 -04:00
' id ' , ' user ' , ' name ' , ' date ' , ' is_public ' , ' collection ' , ' created_at ' , ' updated_at ' , ' items '
2024-08-05 16:09:57 -04:00
]
2025-07-09 23:08:54 -04:00
read_only_fields = [ ' id ' , ' created_at ' , ' updated_at ' , ' user ' ]
2024-08-05 21:36:38 -04:00
def create ( self , validated_data ) :
items_data = validated_data . pop ( ' checklistitem_set ' )
checklist = Checklist . objects . create ( * * validated_data )
2025-06-08 13:15:43 -04:00
2024-08-05 21:36:38 -04:00
for item_data in items_data :
2025-07-09 23:08:54 -04:00
# Remove user from item_data to avoid constraint issues
item_data . pop ( ' user ' , None )
# Set user from the parent checklist
2025-06-08 13:15:43 -04:00
ChecklistItem . objects . create (
checklist = checklist ,
2025-07-09 23:08:54 -04:00
user = checklist . user ,
2025-06-08 13:15:43 -04:00
* * item_data
)
2024-08-05 21:36:38 -04:00
return checklist
def update ( self , instance , validated_data ) :
items_data = validated_data . pop ( ' checklistitem_set ' , [ ] )
# Update Checklist fields
for attr , value in validated_data . items ( ) :
setattr ( instance , attr , value )
instance . save ( )
# Get current items
current_items = instance . checklistitem_set . all ( )
current_item_ids = set ( current_items . values_list ( ' id ' , flat = True ) )
# Update or create items
updated_item_ids = set ( )
for item_data in items_data :
2025-07-09 23:08:54 -04:00
# Remove user from item_data to avoid constraint issues
item_data . pop ( ' user ' , None )
2025-06-08 13:15:43 -04:00
2024-08-05 21:36:38 -04:00
item_id = item_data . get ( ' id ' )
if item_id :
if item_id in current_item_ids :
item = current_items . get ( id = item_id )
for attr , value in item_data . items ( ) :
setattr ( item , attr , value )
item . save ( )
updated_item_ids . add ( item_id )
else :
# If ID is provided but doesn't exist, create new item
2025-06-08 13:15:43 -04:00
ChecklistItem . objects . create (
checklist = instance ,
2025-07-09 23:08:54 -04:00
user = instance . user ,
2025-06-08 13:15:43 -04:00
* * item_data
)
2024-08-05 21:36:38 -04:00
else :
# If no ID is provided, create new item
2025-06-08 13:15:43 -04:00
ChecklistItem . objects . create (
checklist = instance ,
2025-07-09 23:08:54 -04:00
user = instance . user ,
2025-06-08 13:15:43 -04:00
* * item_data
)
2024-08-05 21:36:38 -04:00
# Delete items that are not in the updated data
items_to_delete = current_item_ids - updated_item_ids
instance . checklistitem_set . filter ( id__in = items_to_delete ) . delete ( )
return instance
2024-08-05 16:09:57 -04:00
def validate ( self , data ) :
# Check if the collection is public and the checklist is not
collection = data . get ( ' collection ' )
is_public = data . get ( ' is_public ' , False )
if collection and collection . is_public and not is_public :
raise serializers . ValidationError (
' Checklists associated with a public collection must be public. '
)
return data
2024-11-17 16:34:46 -05:00
class CollectionSerializer ( CustomModelSerializer ) :
2025-07-09 23:08:54 -04:00
locations = LocationSerializer ( many = True , read_only = True )
2024-07-27 19:22:01 -04:00
transportations = TransportationSerializer ( many = True , read_only = True , source = ' transportation_set ' )
2024-08-03 21:09:49 -04:00
notes = NoteSerializer ( many = True , read_only = True , source = ' note_set ' )
2024-08-05 18:48:11 -04:00
checklists = ChecklistSerializer ( many = True , read_only = True , source = ' checklist_set ' )
2025-02-08 16:10:01 -05:00
lodging = LodgingSerializer ( many = True , read_only = True , source = ' lodging_set ' )
2024-07-27 19:22:01 -04:00
class Meta :
model = Collection
2025-07-09 23:08:54 -04:00
fields = [ ' id ' , ' description ' , ' user ' , ' name ' , ' is_public ' , ' locations ' , ' created_at ' , ' start_date ' , ' end_date ' , ' transportations ' , ' notes ' , ' updated_at ' , ' checklists ' , ' is_archived ' , ' shared_with ' , ' link ' , ' lodging ' ]
read_only_fields = [ ' id ' , ' created_at ' , ' updated_at ' , ' user ' ]
2024-09-02 10:29:51 -04:00
def to_representation ( self , instance ) :
representation = super ( ) . to_representation ( instance )
# Make it display the user uuid for the shared users instead of the PK
shared_uuids = [ ]
for user in instance . shared_with . all ( ) :
shared_uuids . append ( str ( user . uuid ) )
representation [ ' shared_with ' ] = shared_uuids
2025-02-05 19:38:04 -05:00
return representation