Объект '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,
    }
Вернуться на верх