Доступ к сериализатору через переменную в drf
В методе create в моем сериализаторе я пытаюсь отправить часть проверенных данных в другой сериализатор, как показано ниже:
new_serializer = NewSerializer(validated_data.get('customer'))
new_serializer.save()
Но в месте NewSerializer я хочу иметь возможность использовать переменную. Это позволит мне выбирать сериализаторы динамически. Что-то вроде этого:
the_serializer = "NewSerializer"
new_serializer = the_serializer(validated_data.get('customer'))
Есть ли способ достичь этого?
Из вашего вопроса я понял, что вы хотите инстанцировать класс, где имя класса предоставляется переменной.
Для этого можно использовать getattr, однако необходимо знать, в каком модуле находится инстанцируемый класс.
Например, если ваш класс сериализатора определен в модуле foo.py, вы можете сделать что-то вроде:
import foo
from yourapp.serializers import DefaultSerializer
the_serializer = "NewSerializer"
SerializerClass = getattr(foo, the_serializer, DefaultSerializer)
args = ("args", "to", "your", "serializer")
serializer_object = SerializerClass(*args)
Или в случае, если вам нужно обрабатывать ошибочные имена сериализаторов:
try:
SerializerClass = getattr(foo, the_serializer, DefaultSerializer)
args = ("args", "to", "your", "serializer")
serializer_object = SerializerClass(*args)
except AttributeError as ae:
print(f"{ae}")
# handle exception here
Однако такой подход к инстанцированию имени класса не кажется мне привлекательным. Должен быть какой-то лучший способ сделать то, что вы пытаетесь сделать.
Я нашел способ сделать это с помощью import_string в django. У меня присутствовали имя_приложения и имя_модели, которые использовались для импорта сериализатора. Все мои сериализаторы названы в формате {имя_модели}Serializer, поэтому этот способ мне подошел.
serializer_name = import_string(f"{app_name}.serializers {model_name}Serializer")
ins = serializer_name(data = main_data)
if ins.is_valid():
ins.save()
Вот ссылка на документацию django.
https://docs.djangoproject.com/en/4.0/ref/utils/?fbclid=IwAR22qaDgk0xT9nOY0lP4s3tVh2aKEleefFWQf_L6th5I0DQ56RUMpUmskpo#module-django.utils.module_loading