Get the context for outputing raw json in api and admin, no looping over the fields anymore
This commit is contained in:
@@ -74,11 +74,12 @@ class TranslatableMixin:
|
||||
if not self.translatable:
|
||||
return value
|
||||
|
||||
# Check if we're in admin context by looking at the call stack
|
||||
# Check if we're in admin or API context by looking at the call stack
|
||||
frames = inspect.getouterframes(inspect.currentframe())
|
||||
is_admin_context = os.environ.get('DJANGO_ADMIN_OVERRIDE', False) == '1' or any('admin' in frame.filename or 'forms' in frame.filename for frame in frames[:5])
|
||||
is_api_context = any('serializers' in frame.filename or 'rest_framework' in frame.filename or '/api/' in frame.filename for frame in frames[:10])
|
||||
|
||||
logging.debug(f"{self.__class__.__name__} from_db_value - admin context: {is_admin_context}")
|
||||
logging.debug(f"{self.__class__.__name__} from_db_value - admin context: {is_admin_context}, api context: {is_api_context}")
|
||||
|
||||
try:
|
||||
translations = json.loads(value) if isinstance(value, str) else value
|
||||
@@ -87,10 +88,10 @@ class TranslatableMixin:
|
||||
|
||||
logging.debug(f"{self.__class__.__name__} from_db_value - parsed translations: {translations}")
|
||||
|
||||
# For admin/forms, return the full dict so widgets can access all translations
|
||||
if is_admin_context:
|
||||
# For admin/forms/API, return the full dict so serializers/widgets can access all translations
|
||||
if is_admin_context or is_api_context:
|
||||
logging.debug(
|
||||
f"{self.__class__.__name__} from_db_value - returning full dict for admin: {translations}")
|
||||
f"{self.__class__.__name__} from_db_value - returning full dict for admin/api: {translations}")
|
||||
return translations
|
||||
|
||||
# For regular use, return the appropriate language
|
||||
|
||||
@@ -75,7 +75,7 @@ class TranslatableSerializerMixin:
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._setup_translatable_fields()
|
||||
|
||||
|
||||
def _setup_translatable_fields(self):
|
||||
"""Identify and setup translatable fields in the serializer"""
|
||||
self._translatable_fields = []
|
||||
@@ -184,19 +184,8 @@ class TranslatableSerializerMixin:
|
||||
if field_name in validated_data:
|
||||
new_value = validated_data[field_name]
|
||||
|
||||
# Get RAW value from database using raw SQL (bypass ALL descriptors)
|
||||
from django.db import connection
|
||||
model_class = instance.__class__
|
||||
table_name = model_class._meta.db_table
|
||||
pk_field = model_class._meta.pk.name
|
||||
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(
|
||||
f"SELECT {field_name} FROM {table_name} WHERE {pk_field} = %s",
|
||||
[instance.pk]
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
existing_value = row[0] if row else None
|
||||
# Get existing value (model field returns dict in API context)
|
||||
existing_value = getattr(instance, field_name, None)
|
||||
|
||||
# Parse existing value
|
||||
existing_translations = {}
|
||||
@@ -271,10 +260,17 @@ class TranslatableField(serializers.Field):
|
||||
|
||||
def to_representation(self, value):
|
||||
"""Convert database value to API representation"""
|
||||
# Get lang parameter from request if not set explicitly on field
|
||||
request_language = self.language
|
||||
if not request_language and hasattr(self, 'parent') and self.parent:
|
||||
if hasattr(self.parent, 'context') and 'request' in self.parent.context:
|
||||
request = self.parent.context['request']
|
||||
request_language = request.query_params.get('lang') or request.query_params.get('language')
|
||||
|
||||
if not value:
|
||||
return '' if self.language else {}
|
||||
|
||||
# Handle JSON string from database
|
||||
return '' if request_language else {}
|
||||
|
||||
# Value is already a dict in API context (from model field's from_db_value)
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
translations = json.loads(value)
|
||||
@@ -284,11 +280,11 @@ class TranslatableField(serializers.Field):
|
||||
translations = value
|
||||
else:
|
||||
translations = {'en': str(value)}
|
||||
|
||||
|
||||
# Return specific language or full dict
|
||||
if self.language:
|
||||
if self.language in translations:
|
||||
return translations[self.language]
|
||||
if request_language:
|
||||
if request_language in translations:
|
||||
return translations[request_language]
|
||||
elif 'en' in translations:
|
||||
return translations['en']
|
||||
elif translations:
|
||||
|
||||
Reference in New Issue
Block a user