Python Django - Попытка сделать динамическое имя из строки для вызова функции сериализатора
Я пытался получить доступ к сериализатору, используя имя сериализатора и набор запросов модели в качестве параметра, используя функцию python gettattr(). После выполнения кода Django возвращает следующую ошибку:
'str' object has no attribute '<module 'django.db.models' from 'C:\\Python310\\lib\\site-packages\\django\\db\\models\\__init__.py'>'
Однако я не могу понять, что это значит, я застрял на попытке получить доступ к сериализатору таким образом, так как у меня есть dyanmic url.
Любая помощь в решении проблемы или объяснение ошибки будут оценены по достоинству.
Я ожидал, что сериализатор будет нормально обрабатываться и возвращать данные в ответ, я реализовал это таким образом.
@api_view(['GET'])
def List_all_part(request, part):
table = apps.get_model('Parts', part)
model = table.objects.all()
serializer = getattr(str(part.lower()), str(models))
return Response(serializer.data)
Мне кажется, у вас опечатка в models
.
@api_view(['GET'])
def List_all_part(request, part):
table = apps.get_model('Parts', part)
model = table.objects.all()
- serializer = getattr(str(part.lower()), str(models))
+ serializer = getattr(str(part.lower()), str(model))
return Response(serializer.data)
getattr
не принимает string
в качестве первого аргумента. Вы должны передать object/instance
In [8]: class Test:
...: def __init__(self):
...: self.foo = "bar"
...: def bar(self):
...: return "foo"
...:
In [9]: t = Test()
In [10]: getattr(t, "foo")
Out[10]: 'bar'
In [11]: getattr(t, "bar")()
Out[11]: 'foo'
In [12]:
Что вам нужно, так это загрузить ваш класс сериализатора из модуля, в котором он определен. Вы можете использовать getattr, но вам нужно использовать в качестве первого параметра объект загруженного модуля, а не строку. Поэтому просто импортируйте модуль сериализатора и передайте его в качестве первого аргумента getattr.
Также вы можете использовать другие средства для динамической загрузки классов, но это будет проще. Также результатом getattr будет нужный класс сериализатора, после чего вам нужно вызвать его с данными, которые вы хотите сериализовать. Например,
import serializers
@api_view(['GET'])
def List_all_part(request, part):
table = apps.get_model('Parts', part)
model = table.objects.all()
serializer_class = getattr(serializers, str(models))
serializer = serializer_class(model, many=True)
return Response(serializer.data)
я не уверен, что понял вашу проблему, но лучший способ использовать динамический сериализатор - это создать функцию, которая будет возвращать нужный сериализатор. example:
@api_view(['GET'])
def List_all_part(request, part):
table = apps.get_model('Parts', part)
model = table.objects.all()
serializer = dynamic_serializer(model.model)
return Response(serializer.data)
а определение функции dynamic_serializer будет выглядеть так:
def dynamic_serializer(model_class):
class DynamicSerializer(serializers.ModelSerializer):
class Meta:
model = model_class
if model_class == cpu:
fields = ('id', 'field_cpu1', 'field_cpu2', 'field_cpu3')
elif model_class == other_model:
fields = ('id', 'field_other_model1', 'field_other_model2', 'field_other_model3')
else:
fields = ('id', 'field_another_model1', 'field_another_model2', 'field_another_model3')
return DynamicSerializer
<