Проблема
Метод to_representation
SlugRelatedField кодируется так, чтобы возвращать значение ключевого аргумента slug_field
, который вы передаете ему во время инициализации.
Обходные пути
Расширьте SlugRelatedField
и переопределите его to_representation
методом, чтобы вернуть полный объект вместо слага.Это может быть немного сложно, потому что фактический экземпляр модели не является частью класса.
Имеют два поля, одно для слаг и другое для фактического объекта.Это проще реализовать.
Вот как вы можете реализовать второй обходной путь:
venue = VenueSerializer(read_only=True)
venue_id = serializers.SlugRelatedField(
write_only=True
allow_null=True,
queryset=Venue.objects.all(),
required=False,
slug_field='id')
ОБНОВЛЕНИЕ : Это, по-видимому, довольноРазыскиваемая функция в DRF.Я также нашел способ реализовать первый обходной путь.Он имеет дело с PrimaryKeyRelatedField
, но вы, вероятно, можете изменить его для работы с SlugRelatedField
.Вот оно:
from collections import OrderedDict
from rest_framework import serializers
class AsymetricRelatedField(serializers.PrimaryKeyRelatedField):
def to_representation(self, value):
return self.serializer_class(value).data
def get_queryset(self):
if self.queryset:
return self.queryset
return self.serializer_class.Meta.model.objects.all()
def get_choices(self, cutoff=None):
queryset = self.get_queryset()
if queryset is None:
return {}
if cutoff is not None:
queryset = queryset[:cutoff]
return OrderedDict([
(
item.pk,
self.display_value(item)
)
for item in queryset
])
def use_pk_only_optimization(self):
return False
@classmethod
def from_serializer(cls, serializer, name=None, args=(), kwargs={}):
if name is None:
name = f"{serializer.__class__.name}AsymetricAutoField"
return type(name, [cls], {"serializer_class": serializer})
Затем вы можете использовать это поле следующим образом:
class FooSerializer(serilizers.ModelSerializer):
bar = AsymetricRelatedField(BarSerializer)
class Meta:
model = Foo
Вы можете найти оригинальное обсуждение этого здесь