Объект 'float' не является итерируемым в кверисете django
class TransactionHistoryListSerializer(serializers.BaseSerializer):
class Meta:
model = CustomerVisit
def to_representation(self, instance):
price = 0
package_price = booking_models.TestBooking.objects.filter(customer_visit=instance).values_list(
"package__test__test_mrp", flat=True
)[0]
for price in package_price:
pass
return {
"visit_id": instance.id,
"customer_name": {
"salutation": instance.customer.salutation,
"first_name": instance.customer.first_name,
"middle_name": instance.customer.middle_name,
"last_name": instance.customer.last_name,
},
"dob": instance.customer.date_of_birth,
"amount": sum([k.amount for k in booking_models.TestBooking.objects.filter(customer_visit=instance)])
+ (price if price else 0),
"discount": sum([k.discount for k in booking_models.TestBooking.objects.filter(customer_visit=instance)]),
"paid_amount": sum([k.amount for k in payment_models.Payment.objects.filter(customer_visit=instance)]),
}
Здесь tes_mrp имеет тип float.
Я искал и получил решение использовать list comprehension, но все еще не работает. Я пробовал [[price] for price in package_price]
, for price in package_price: a = list(str(price))
, но все равно получаю, что объект float не является итерируемым. Наверняка я делаю что-то не так. Кто-нибудь может помочь. Спасибо!!!
Вызывает в этой строке - for price in package_price:
Правильно, это потому, что вы делаете .values_list(..., flat=True)
, который возвращает список, а затем индексируете его с помощью [0]
, так что вы получаете первое значение. Таким образом, package_price
действительно является float, и, как говорит ошибка, вы не можете выполнять итерацию над одним float.
Таким образом, этот конкретный бит можно исправить, просто убрав этот [0]
.
Ваш код можно упростить, чтобы не повторять запросы и использовать агрегаты Django:
def to_representation(self, instance):
bookings = booking_models.TestBooking.objects.filter(customer_visit=instance)
payments = payment_models.Payment.objects.filter(customer_visit=instance)
package_price = bookings.values_list("package__test__test_mrp", flat=True).first()
booking_amounts = bookings.aggregate(
price_sum=Sum("amount"),
discount_sum=Sum("discount"),
)
payment_amounts = payments.aggregate(
payment_sum=Sum("amount"),
)
return {
"visit_id": instance.id,
"customer_name": {
"salutation": instance.customer.salutation,
"first_name": instance.customer.first_name,
"middle_name": instance.customer.middle_name,
"last_name": instance.customer.last_name,
},
"dob": instance.customer.date_of_birth,
"amount": (booking_amounts.get("price_sum") or 0) + package_price,
"discount": booking_amounts.get("discount_sum") or 0,
"paid_amount": payment_amounts.get("payment_sum") or 0,
}