Add custom exception handler and improve order logic

Introduced a custom DRF exception handler to convert Django ValidationError to DRF ValidationError and registered it in settings. Improved Order model's calculate_total_price method to avoid accessing related fields before the object is saved. Updated OrderCreateSerializer to save the order after adding discounts and payment, ensuring total price is recalculated. Added utility functions and a rounded DateTime field in a new utils.py.
This commit is contained in:
2026-02-01 03:17:49 +01:00
parent 3e4d58f80d
commit f9636d1464
4 changed files with 59 additions and 6 deletions

View File

@@ -0,0 +1,44 @@
import os
from datetime import datetime
from rest_framework.fields import DateTimeField
from django.conf import settings
from django.core.exceptions import ValidationError as DjangoValidationError
from rest_framework.views import exception_handler
from rest_framework.exceptions import ValidationError as DRFValidationError
def custom_exception_handler(exc, context):
"""
Custom exception handler to convert Django ValidationError to DRF ValidationError (400 instead of 500)
"""
# Convert Django ValidationError to DRF ValidationError
if isinstance(exc, DjangoValidationError):
if hasattr(exc, 'error_dict'):
# Multiple field errors
exc = DRFValidationError(detail=exc.message_dict)
elif hasattr(exc, 'error_list'):
# Single error or list of errors
exc = DRFValidationError(detail=exc.messages)
else:
# Fallback
exc = DRFValidationError(detail=str(exc))
# Call REST framework's default exception handler
return exception_handler(exc, context)
def truncate_to_minutes(dt: datetime) -> datetime:
return dt.replace(second=0, microsecond=0)
class RoundedDateTimeField(DateTimeField):
def to_internal_value(self, value):
dt = super().to_internal_value(value)
return truncate_to_minutes(dt)
IMPORT_DIR = "data_imports"
def get_imports_dir():
base_dir = settings.BASE_DIR # adjust if your BASE_DIR is different
imports_dir = os.path.join(base_dir, IMPORT_DIR)
os.makedirs(imports_dir, exist_ok=True)
return imports_dir