from django.http import JsonResponse from django.views.decorators.http import require_http_methods from django.contrib.auth.decorators import login_required from django.contrib.contenttypes.models import ContentType from django.core.exceptions import PermissionDenied from django.shortcuts import get_object_or_404 import json import logging from .models import Photo logger = logging.getLogger(__name__) @login_required @require_http_methods(["POST"]) def upload_photo(request): """Handle photo upload for any model""" try: # Get app label, model, and object ID app_label = request.POST.get('app_label') model = request.POST.get('model') object_id = request.POST.get('object_id') # Log received data logger.debug(f"Received upload request - app_label: {app_label}, model: {model}, object_id: {object_id}") logger.debug(f"Files in request: {request.FILES}") # Validate required fields missing_fields = [] if not app_label: missing_fields.append('app_label') if not model: missing_fields.append('model') if not object_id: missing_fields.append('object_id') if 'image' not in request.FILES: missing_fields.append('image') if missing_fields: return JsonResponse({ 'error': f'Missing required fields: {", ".join(missing_fields)}' }, status=400) # Get content type try: content_type = ContentType.objects.get( app_label=app_label.lower(), model=model.lower() ) except ContentType.DoesNotExist: return JsonResponse({ 'error': f'Invalid content type: {app_label}.{model}' }, status=400) # Get the object instance try: obj = content_type.get_object_for_this_type(id=object_id) except Exception as e: return JsonResponse({ 'error': f'Object not found: {app_label}.{model} with id {object_id}. Error: {str(e)}' }, status=404) # Check if user has permission to add photos if not request.user.has_perm('media.add_photo'): logger.warning(f"User {request.user} attempted to upload photo without permission") return JsonResponse({ 'error': 'You do not have permission to upload photos' }, status=403) # Create the photo photo = Photo.objects.create( image=request.FILES['image'], content_type=content_type, object_id=obj.id, uploaded_by=request.user, # Add the user who uploaded the photo # Set as primary if it's the first photo is_primary=not Photo.objects.filter( content_type=content_type, object_id=obj.id ).exists() ) return JsonResponse({ 'id': photo.id, 'url': photo.image.url, 'caption': photo.caption, 'is_primary': photo.is_primary }) except Exception as e: logger.error(f"Error in upload_photo: {str(e)}", exc_info=True) return JsonResponse({ 'error': f'An error occurred while uploading the photo: {str(e)}' }, status=400) @login_required @require_http_methods(["POST"]) def set_primary_photo(request, photo_id): """Set a photo as primary""" try: photo = get_object_or_404(Photo, id=photo_id) # Check if user has permission to edit photos if not request.user.has_perm('media.change_photo'): return JsonResponse({ 'error': 'You do not have permission to edit photos' }, status=403) # Set this photo as primary photo.is_primary = True photo.save() # This will automatically unset other primary photos return JsonResponse({'status': 'success'}) except Exception as e: logger.error(f"Error in set_primary_photo: {str(e)}", exc_info=True) return JsonResponse({'error': str(e)}, status=400) @login_required @require_http_methods(["POST"]) def update_caption(request, photo_id): """Update a photo's caption""" try: photo = get_object_or_404(Photo, id=photo_id) # Check if user has permission to edit photos if not request.user.has_perm('media.change_photo'): return JsonResponse({ 'error': 'You do not have permission to edit photos' }, status=403) # Update caption data = json.loads(request.body) photo.caption = data.get('caption', '') photo.save() return JsonResponse({ 'id': photo.id, 'caption': photo.caption }) except Exception as e: logger.error(f"Error in update_caption: {str(e)}", exc_info=True) return JsonResponse({'error': str(e)}, status=400) @login_required @require_http_methods(["DELETE"]) def delete_photo(request, photo_id): """Delete a photo""" try: photo = get_object_or_404(Photo, id=photo_id) # Check if user has permission to delete photos if not request.user.has_perm('media.delete_photo'): return JsonResponse({ 'error': 'You do not have permission to delete photos' }, status=403) photo.delete() return JsonResponse({'status': 'success'}) except Exception as e: logger.error(f"Error in delete_photo: {str(e)}", exc_info=True) return JsonResponse({'error': str(e)}, status=400)