Проблема доступа к глубоко вложенным атрибутам в методе validate сериализатора Django Rest Framework

Я столкнулся с проблемой при попытке получить доступ к глубоко вложенным атрибутам в методе validate сериализатора Django Rest Framework. Вот упрощенная версия моего сериализатора:

from rest_framework import serializers
from myapp.models import User

class YourSerializer(serializers.ModelSerializer):

    def validate(self, attrs):
        if hasattr(self.parent.instance, 'vehicle'):
            if hasattr(self.parent.instance.vehicle, 'engine'):
                if hasattr(self.parent.instance.vehicle.engine, 'fuel'):
                    fuel_type = self.parent.instance.vehicle.engine.fuel.diesel
                    if fuel_type:
                        pass
                    else:
                        raise serializers.ValidationError("Fuel type is not available.")
                else:
                    raise serializers.ValidationError("Fuel attribute is not available.")
            else:
                raise serializers.ValidationError("Engine attribute is not available.")
        else:
            raise serializers.ValidationError("Vehicle attribute is not available.")
        
        return attrs

В методе validate я пытаюсь получить доступ к глубоко вложенным атрибутам (vehicle.engine.fuel.diesel) родительского экземпляра. Дело в том, что модель двигателя создается после того, как пользователь выполнит операции ABC, то же самое относится и к топливу, и к дизелю. Когда множество людей работают над над кодовой базой, трудно определить, созданы ли эти Модели или нет. Обычно используются getattr() и hasattr(), но их частое использование приводит к тому, что код выглядит беспорядочно. код выглядит грязным.

Пробовал статические луты, такие как mypy и pylint, они помогают в некоторой степени, но иногда всплывают проблемы TypeError, NoneType. Не знаю, как их исправить.

Спасибо за помощь!

AttributeError поднимается с отсутствующим атрибутом, сохраненным как name, поэтому вы можете просто попробовать обратиться к самому глубокому вложенному атрибуту напрямую и использовать единственный обработчик ошибок для повторного поднятия исключения с более дружелюбным сообщением:

attr_display_name = {
    'diesel': 'Fuel type'
}

def validate(self, attrs):
    try:
        self.parent.instance.vehicle.engine.fuel.diesel
    except AttributeError as e:
        raise serializers.ValidationError(
            attr_display_name.get(e.name, f'{e.name.title()} attribute') +
            ' is not available.'
        )
    return attrs
Вернуться на верх