Преобразование полей внутри сериализатора в django
У меня есть проект, в котором одна модель, называемая Request
, имеет два поля (source
, dest
), которые содержат два id
, которые не известны пользователю. Однако каждая из них связана с другой моделью User
, которая, допустим, имеет одно поле username
, которое является известным пользователю.
Теперь я хочу сделать сериализатор, который может принимать username
и преобразовывать их в id
. (Обратного было легко добиться, я просто модифицировал метод to_representation
.) Проблема в том, что когда я посылаю {'source': 'john', 'dest': 'jim'}
, сериализатор не воспринимает эти данные как действительные. Это было ожидаемое поведение, так как он ожидал id
s и получил строки (username
s). Однако, даже когда я переопределил методы validate_source
, validate_dest
и validate
, чтобы на самом деле проверить, что username
существуют (вместо id
), я все равно получаю ошибки, что сериализатор ожидал id
, а получил string.
- Методы
validate
,validate_<field>
являются неправильными для переопределения в данном случае? - Должен ли я просто преобразовать
username
s вid
s внутри моего представления? - является ли питоническим и хорошей практикой, с точки зрения django, получать некоторые поля от пользователя и изменять их внутри сериализатора (как я изменяю
username
вid
)?
Текущий сериализатор:
class RequestSerializer(serializers.ModelSerializer):
class Meta:
model = Request
fields = '__all__'
def validate_source(self, value):
username = value.get('username')
if username is None:
raise serializers.ValidationError('`user` field is required ')
return value
def validate_dest(self, value):
username = value.get('username')
if username is None:
raise serializers.ValidationError('`user` field is required ')
return value
def validate(self, attrs):
self.validate_source(attrs['source'])
self.validate_dest(attrs['dest'])
return attrs
def to_representation(self, instance):
# do things
pass
Обратите внимание, что это не вся функциональность моего сериализатора. Для преобразования из id
в username
мне нужно проверить данные другой модели, поэтому я не могу использовать SlugRelatedField.
Спасибо.
Вы, вероятно, можете работать с SlugRelatedField
[drf-doc]:
from rest_framework import serializers
class MyModelSerializer(serializers.ModelSerializer):
source = serializers.SlugRelatedField(
queryset=User.objects.all(),
slug_field='username',
)
dest = serializers.SlugRelatedField(
queryset=User.objects.all(),
slug_field='username',
)
class Meta:
model = MyModel
fields = ('source', 'dest')
Это вернет username
поля source
и dest
объекта модели, а в обратном направлении будет получено User
с соответствующим именем пользователя.