prije gemini provjere
This commit is contained in:
98
001.BACKEND/operations/mixins.py
Normal file
98
001.BACKEND/operations/mixins.py
Normal file
@@ -0,0 +1,98 @@
|
||||
# operations/mixins.py
|
||||
from django.db import transaction
|
||||
from rest_framework import serializers
|
||||
from rest_framework import status
|
||||
|
||||
class DynamicFieldsModelSerializerMixin:
|
||||
"""
|
||||
Slojeviti Mixin za SERIALIZERE.
|
||||
Čisti prazne stringove iz FormData i dinamički uvozi ugniježđene relacije (Lazy Load).
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
request = self.context.get('request')
|
||||
|
||||
# Ako smo na GET zahtjevu, automatski aktiviramo ugniježđeni prikaz (Read-only)
|
||||
if request and request.method == 'GET':
|
||||
self._setup_nested_serializers()
|
||||
|
||||
def _setup_nested_serializers(self):
|
||||
nested_config = getattr(self.Meta, 'nested_fields_config', {})
|
||||
for field_name, serializer_path in nested_config.items():
|
||||
if field_name in self.fields:
|
||||
try:
|
||||
module_path, class_name = serializer_path.rsplit('.', 1)
|
||||
module = __import__(module_path, fromlist=[class_name])
|
||||
serializer_class = getattr(module, class_name)
|
||||
|
||||
self.fields[field_name] = serializer_class(read_only=True, context=self.context)
|
||||
except (ImportError, AttributeError) as e:
|
||||
print(f"[Mixin Error] Neuspješan dinamički uvoz za {serializer_path}: {e}")
|
||||
|
||||
def to_internal_value(self, data):
|
||||
if hasattr(data, 'dict'): # Pretvara prazne HTML stringove "" u prave Python None vrijednosti
|
||||
data = data.copy()
|
||||
for key, value in data.items():
|
||||
if value == '':
|
||||
data[key] = None
|
||||
return super().to_internal_value(data)
|
||||
|
||||
|
||||
class AstroBridgeViewSetMixin:
|
||||
"""
|
||||
Slojeviti Mixin za VIEWSETOVE.
|
||||
Presreće perform_create/update za automatsko spremanje request.FILES u galerije
|
||||
i omata izlazni JSON u standardni omotač (Envelope) za Astro proxy.
|
||||
"""
|
||||
auto_handle_files = False
|
||||
file_field_name = 'slike'
|
||||
related_file_model = None
|
||||
related_file_fk = None
|
||||
|
||||
def finalize_response(self, request, response, *args, **kwargs):
|
||||
"""Omata DRF odgovor u stabilnu strukturu za Astro klijent."""
|
||||
if isinstance(response.data, (dict, list)):
|
||||
if status.is_success(response.status_code):
|
||||
response.data = {
|
||||
"success": True,
|
||||
"data": response.data,
|
||||
"errors": None
|
||||
}
|
||||
else:
|
||||
response.data = {
|
||||
"success": False,
|
||||
"data": None,
|
||||
"errors": response.data
|
||||
}
|
||||
return super().finalize_response(request, response, *args, **kwargs)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
instance = serializer.save()
|
||||
if self.auto_handle_files:
|
||||
self._process_attached_files(instance)
|
||||
return instance
|
||||
|
||||
def perform_update(self, serializer):
|
||||
instance = serializer.save()
|
||||
if self.auto_handle_files:
|
||||
self._process_attached_files(instance)
|
||||
return instance
|
||||
|
||||
def _process_attached_files(self, instance):
|
||||
"""Automatski izvlači višestruki upload iz FormData boundary-ja."""
|
||||
request = self.request
|
||||
if not self.related_file_model or not self.related_file_fk:
|
||||
return
|
||||
|
||||
files = request.FILES.getlist(self.file_field_name)
|
||||
opis = request.data.get('slika_opis', f"Prilog uz {str(instance)}")
|
||||
|
||||
for f in files:
|
||||
build_kwargs = {
|
||||
self.related_file_fk: instance,
|
||||
'slika': f,
|
||||
}
|
||||
if hasattr(self.related_file_model, 'opis'):
|
||||
build_kwargs['opis'] = opis
|
||||
|
||||
self.related_file_model.objects.create(**build_kwargs)
|
||||
Reference in New Issue
Block a user