Open MehdiDRISSIB opened 3 years ago
Hello,
After some works, I just created this class to show Options request with all fields in translations. I override get_serializer_info to show the fields in the related_model
import types
from collections import OrderedDict
from rest_framework.metadata import SimpleMetadata
from django.core.exceptions import PermissionDenied
from django.http import Http404
from rest_framework import exceptions, serializers
from rest_framework.request import clone_request
from parler.models import TranslatedFieldsModelBase
from parler_rest.fields import TranslatedFieldsField
from typing import Type
from django.db import models
#@lru_cache
def model_serializer(model: Type[models.Model]) -> Type[serializers.ModelSerializer]:
meta_class = types.new_class("Meta")
setattr(meta_class, "model", model)
setattr(meta_class, "fields", "__all__")
result = types.new_class(
model.__name__ + "Serializer", (serializers.ModelSerializer,), {}
)
setattr(result, "Meta", meta_class)
return result
class Metadata(SimpleMetadata):
def determine_actions(self, request, view):
actions = {}
for method in {'PUT', 'POST', 'GET'} & set(view.allowed_methods):
view.request = clone_request(request, method)
try:
# Test global permissions
if hasattr(view, 'check_permissions'):
view.check_permissions(view.request)
# Test object permissions
if method == 'PUT' and hasattr(view, 'get_object'):
view.get_object()
except (exceptions.APIException, PermissionDenied, Http404):
pass
else:
# If user has appropriate permissions for the view, include
# appropriate metadata about the fields that should be supplied.
serializer = view.get_serializer()
actions[method] = self.get_serializer_info(serializer)
finally:
view.request = request
return actions
#return super(Metadata, self).determine_actions(request, view)
def get_serializer_info(self, serializer):
"""
Given an instance of a serializer, return a dictionary of metadata
about its fields.
"""
if hasattr(serializer, 'child'):
# If this is a `ListSerializer` then we want to examine the
# underlying child serializer instance instead.
serializer = serializer.child
serializer_info = OrderedDict()
for field_name, field in serializer.fields.items():
if not isinstance(field, serializers.HiddenField):
if isinstance(field, (TranslatedFieldsField)):
translatable_fields = field.shared_model._parler_meta.get_all_fields()
for _field in serializer.Meta.model._meta.get_fields():
if isinstance(_field.related_model, TranslatedFieldsModelBase):
TranslatableModelSerializer = model_serializer(_field.related_model)
TranslatableSerializer = TranslatableModelSerializer()
for translatable_field in translatable_fields:
translatable_serializer_field = TranslatableSerializer.fields.get(translatable_field)
serializer_info.update({translatable_field: self.get_field_info(translatable_serializer_field)})
else:
serializer_info.update({field_name: self.get_field_info(field)})
return serializer_info
This class is added to REST_FRAMEWORK variable in settings.py:
REST_FRAMEWORK = {
'DEFAULT_METADATA_CLASS': 'apps.utils.metadata.Metadata',
....
I hope this will help someone
Hello,
Is there is any way to show all details of each field in TranslatedFieldsField in serializer in OPTIONS request ?
Currently, when calling OPTIONS request, I have :
But I want also all the description of each field in 'translations' (TranslatedFieldsField)
Many thanks for your answers