mirror of
https://github.com/dartdavros/chatballs.git
synced 2026-10-05 17:14:59 +03:00
- DRF defaults: SessionAuthentication, IsAuthenticated, JSON-only render/parse
- shared api package: IsOwner permission (audits denials) and an exception
handler that flattens every error body to the {detail} SPA contract
- products views rewritten as APIView with permission_classes; manual JSON
parsing and auth checks removed (DRF parser returns 400 on bad JSON)
- response shapes and status codes preserved; product tests use DRF APIClient
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
26 lines
872 B
Python
26 lines
872 B
Python
from typing import Any
|
|
|
|
from rest_framework.views import exception_handler as drf_exception_handler
|
|
|
|
|
|
def _flatten(data: Any) -> str:
|
|
if isinstance(data, str):
|
|
return data
|
|
if isinstance(data, dict):
|
|
return "; ".join(_flatten(value) for value in data.values())
|
|
if isinstance(data, (list, tuple)):
|
|
return "; ".join(_flatten(item) for item in data)
|
|
return str(data)
|
|
|
|
|
|
def api_exception_handler(exc: Exception, context: dict[str, Any]):
|
|
"""Normalize every DRF error body to the SPA contract: {"detail": "<text>"}."""
|
|
response = drf_exception_handler(exc, context)
|
|
if response is None:
|
|
return None
|
|
data = response.data
|
|
if isinstance(data, dict) and list(data.keys()) == ["detail"] and isinstance(data["detail"], str):
|
|
return response
|
|
response.data = {"detail": _flatten(data)}
|
|
return response
|