Django Rest Framework множественная сериализация моделей
Я использую Django Rest Framework для создания API. У меня есть конечная точка, которую я хочу использовать для генерации JSON объекта, содержащего данные из различных моделей. Набор представлений для модели таков:
class InvoiceView(viewsets.ModelViewSet):
def list(self, request):
cart_id = request.data["cart_id"]
shop = Shop.objects.get(id=request.user.id)
cart = ShoppingSession.objects.get(id=cart_id)
cart_items = CartItem.objects.filter(session=cart_id)
paymentmethod = PaymentMethod.objects.get(id=cart.payment_method.id)
Invoice = namedtuple('Receipt',('shopname','cart', 'cartitems', 'paymentmethod'))
invoice = Invoice(
shopname = shop,
cart = cart,
cartitems = cart_items,
paymentmethod = paymentmethod
)
serializer = ReceiptSerializer(Invoice)
return Response(serializer.data,)
Используются следующие сериализаторы:
class ShopSerializer(serializers.ModelSerializer):
class Meta:
model = Shop
exclude = ['is_staff', 'is_active', 'start_date']
class ReceiptSerializer(serializers.Serializer):
shopname = ShopSerializer()
cart = ShoppingSessionSerializer()
cartitems = CartItemSerializer(many=True)
paymentmethod = PaymentMethodSerializer()
Когда url запущен и выполняется GET-запрос. Возникает ошибка, которая выглядит следующим образом.
Traceback (most recent call last):
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/rest_framework/viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/home/sean/Development/SKAKEY/shops/views.py", line 280, in list
return Response(serializer.data,)
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/rest_framework/serializers.py", line 555, in data
ret = super().data
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/rest_framework/serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/rest_framework/serializers.py", line 522, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/rest_framework/serializers.py", line 509, in to_representation
attribute = field.get_attribute(instance)
File "/home/sean/anaconda3/envs/skakey/lib/python3.8/site-packages/rest_framework/fields.py", line 490, in get_attribute
raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `first_name` on serializer `ShopSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `_tuplegetter` instance.
Original exception text was: '_collections._tuplegetter' object has no attribute 'first_name'.
Как вы собираетесь использовать несколько сериализаторов в одном классе сериализатора для такого рода пользовательского сценария использования?
Вероятно, вам не нужен namedtuple, вы можете инициализировать сериализатор как
receipt_serializer = ReceiptSerializer(data={
'shop': Shop.objects.get(id=request.user.id).__dict__,
'cart': ShoppingSession.objects.get(id=cart_id).__dict__,
'cart_items': CartItem.objects.filter(session=cart_id).__dict__,
'paymentmethod': PaymentMethod.objects.get(id=cart.payment_method.id).__dict__})
Затем вызовите receipt_serializer.is_valid(), и вы сможете получить вывод из receipt_serializer.data