Как отобразить значение модели ForeignKey в Django Rest Framework
models.py
class Item(models.Model):
name = models.CharField(max_length=100)
# other_no_need_translate = models.CharField(max_length=100)
class Itemi18n(models.Model):
origin = models.ForeignKey(Item, related_name='i18n')
language = models.CharField(max_length=200, default="")
name = models.CharField(max_length=100)
view.py
class ItemViewSet(viewsets.GenericViewSet):
def get_queryset(self):
return Item.objects.annotate(name=F('i18n__name')) # something like this
serializers.py
class I18nField(Field):
def __init__(self, field_attr, **kwargs):
self.field_attr = field_attr
super().__init__(source='*', read_only=True, **kwargs)
def to_representation(self, value) -> str:
request = self.context['request']
if request.query_params.get('lang') == 'es':
value = ...
else:
value = ...
return value
class ItemSerializer(serializers.ModelSerializer):
name = I18nField(...)
Я хочу написать сериализатор, который при необходимости i18n возвращает имя из Itemi18n, в противном случае возвращает имя из Item. Я придумал 2 решения, одно - использовать аннотацию для переопределения поля, другое - использовать Custom Field. Я не уверен в лучших практиках и проблемах с производительностью.
С точки зрения производительности, аннотация будет хуже, поскольку она будет выполнять агрегирование по всем объектам. Лучшим подходом будет, конечно, максимально сузить количество запросов.
Поскольку эта функция является мутацией исходного значения, я считаю, что лучше всего реализовать ее внутри метода serializer
to_representation
.
from django.utils.translation import get_language
class ItemModelSerializer(ModelSerializer):
class Meta:
model = Item
exclude = ["id"]
def to_representation(self, instance):
representation = super().to_representation(instance)
local_lang = get_language()
if local_lang != "en":
try:
translation = instance.i18n.get(language=local_lang)
representation["name"] = translation.name
except Itemi18n.DoesNotExist:
pass
return representation
P.S. Также можно увеличить производительность за счет перехвата связанных объектов.