Преобразование полей внутри сериализатора в django

У меня есть проект, в котором одна модель, называемая Request, имеет два поля (source, dest), которые содержат два id, которые не известны пользователю. Однако каждая из них связана с другой моделью User, которая, допустим, имеет одно поле username, которое является известным пользователю.

Теперь я хочу сделать сериализатор, который может принимать username и преобразовывать их в id. (Обратного было легко добиться, я просто модифицировал метод to_representation.) Проблема в том, что когда я посылаю {'source': 'john', 'dest': 'jim'}, сериализатор не воспринимает эти данные как действительные. Это было ожидаемое поведение, так как он ожидал ids и получил строки (usernames). Однако, даже когда я переопределил методы validate_source, validate_dest и validate, чтобы на самом деле проверить, что username существуют (вместо id), я все равно получаю ошибки, что сериализатор ожидал id, а получил string.

  1. Методы validate, validate_<field> являются неправильными для переопределения в данном случае?
  2. Должен ли я просто преобразовать usernames в ids внутри моего представления?
  3. является ли питоническим и хорошей практикой, с точки зрения 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 с соответствующим именем пользователя.

Вернуться на верх