1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-24 15:29:36 +02:00

feat: Implement Hotel model with CRUD operations and integrate into views and serializers

This commit is contained in:
Sean Morley 2025-02-03 12:28:42 -05:00
parent da9c2ba80a
commit df60184f23
7 changed files with 451 additions and 6 deletions

View file

@ -1,6 +1,6 @@
from django.utils import timezone
import os
from .models import Adventure, AdventureImage, ChecklistItem, Collection, Note, Transportation, Checklist, Visit, Category, Attachment
from .models import Adventure, AdventureImage, ChecklistItem, Collection, Note, Transportation, Checklist, Visit, Category, Attachment, Hotel
from rest_framework import serializers
from main.utils import CustomModelSerializer
from users.serializers import CustomUserDetailsSerializer
@ -303,4 +303,14 @@ class CollectionSerializer(CustomModelSerializer):
shared_uuids.append(str(user.uuid))
representation['shared_with'] = shared_uuids
return representation
class HotelSerializer(CustomModelSerializer):
class Meta:
model = Hotel
fields = [
'id', 'user_id', 'name', 'description', 'rating', 'link', 'check_in', 'check_out',
'reservation_number', 'price', 'latitude', 'longitude', 'location', 'is_public',
'collection', 'created_at', 'updated_at'
]
read_only_fields = ['id', 'created_at', 'updated_at', 'user_id']

View file

@ -18,6 +18,7 @@ router.register(r'ics-calendar', IcsCalendarGeneratorViewSet, basename='ics-cale
router.register(r'overpass', OverpassViewSet, basename='overpass')
router.register(r'search', GlobalSearchView, basename='search')
router.register(r'attachments', AttachmentViewSet, basename='attachments')
router.register(r'hotels', HotelViewSet, basename='hotels')
urlpatterns = [

View file

@ -12,4 +12,5 @@ from .reverse_geocode_view import *
from .stats_view import *
from .transportation_view import *
from .global_search_view import *
from .attachment_view import *
from .attachment_view import *
from .hotel_view import *

View file

@ -0,0 +1,84 @@
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from django.db.models import Q
from adventures.models import Hotel
from adventures.serializers import HotelSerializer
from rest_framework.exceptions import PermissionDenied
from adventures.permissions import IsOwnerOrSharedWithFullAccess
from rest_framework.permissions import IsAuthenticated
class HotelViewSet(viewsets.ModelViewSet):
queryset = Hotel.objects.all()
serializer_class = HotelSerializer
permission_classes = [IsOwnerOrSharedWithFullAccess]
def list(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return Response(status=status.HTTP_403_FORBIDDEN)
queryset = Hotel.objects.filter(
Q(user_id=request.user.id)
)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
def get_queryset(self):
user = self.request.user
if self.action == 'retrieve':
# For individual adventure retrieval, include public adventures, user's own adventures and shared adventures
return Hotel.objects.filter(
Q(is_public=True) | Q(user_id=user.id) | Q(collection__shared_with=user.id)
).distinct().order_by('-updated_at')
# For other actions, include user's own adventures and shared adventures
return Hotel.objects.filter(
Q(user_id=user.id) | Q(collection__shared_with=user.id)
).distinct().order_by('-updated_at')
def partial_update(self, request, *args, **kwargs):
# Retrieve the current object
instance = self.get_object()
user = request.user
# Partially update the instance with the request data
serializer = self.get_serializer(instance, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
# Retrieve the collection from the validated data
new_collection = serializer.validated_data.get('collection')
if new_collection is not None and new_collection != instance.collection:
# Check if the user is the owner of the new collection
if new_collection.user_id != user or instance.user_id != user:
raise PermissionDenied("You do not have permission to use this collection.")
elif new_collection is None:
# Handle the case where the user is trying to set the collection to None
if instance.collection is not None and instance.collection.user_id != user:
raise PermissionDenied("You cannot remove the collection as you are not the owner.")
# Perform the update
self.perform_update(serializer)
# Return the updated instance
return Response(serializer.data)
def perform_update(self, serializer):
serializer.save()
# when creating an adventure, make sure the user is the owner of the collection or shared with the collection
def perform_create(self, serializer):
# Retrieve the collection from the validated data
collection = serializer.validated_data.get('collection')
# Check if a collection is provided
if collection:
user = self.request.user
# Check if the user is the owner or is in the shared_with list
if collection.user_id != user and not collection.shared_with.filter(id=user.id).exists():
# Return an error response if the user does not have permission
raise PermissionDenied("You do not have permission to use this collection.")
# if collection the owner of the adventure is the owner of the collection
serializer.save(user_id=collection.user_id)
return
# Save the adventure with the current user as the owner
serializer.save(user_id=self.request.user)