Проблема с запросами в Django Rest Framework при использовании filter()

вот моя модель:

class PmPrice(models.Model):
    created_at = models.DateTimeField()
    price = models.DecimalField(max_digits=6, decimal_places=2)
    listing = models.ForeignKey("PmListing", models.DO_NOTHING)
    seller = models.ForeignKey("PmSeller", models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = "pm_price"

вот мой сериализатор:

class PmPriceListSerializer(serializers.ModelSerializer):
    url = serializers.ReadOnlyField(source="listing.url")
    shop = serializers.ReadOnlyField(source="listing.shop.name")
    name = serializers.ReadOnlyField(source="listing.product.name")
    ean = serializers.ReadOnlyField(source="listing.product.ean")
    uvp = serializers.ReadOnlyField(source="listing.product.uvp")
    sku = serializers.ReadOnlyField(source="listing.product.sku")
    seller = serializers.ReadOnlyField(source="seller.name")

    class Meta:
        model = PmPrice
        fields = (
            "url",
            "shop",
            "name",
            "ean",
            "sku",
            "uvp",
            "price",
            "created_at",
            "seller",
        )

    def to_representation(self, instance):
        data = super().to_representation(instance)
        return data

а это метод внутри моего класса filters.py, который я использую в своем представлении, и это вызывает у меня головную боль:

def get_by_last_two_cheapest(self, queryset, name, value):
        latest_date_subquery = (
            queryset.annotate(datum=TruncDate("created_at"))
            .values("datum")
            .order_by("-datum")
            .annotate(latest_date=Max("datum"))
            .values("latest_date")[:1]
        )

        # Second subquery to get the second latest date
        second_latest_subquery = (
            queryset.filter(
                created_at__date__lt=Subquery(latest_date_subquery),
            )
            .annotate(datum=TruncDate("created_at"))
            .values("datum")
            .order_by("-datum")
            .annotate(latest_date=Max("datum"))
            .values("latest_date")[:1]
        )

        # Concatenate the results of the subqueries to get the dates
        dates = list()
        dates.append(str(latest_date_subquery[0]["latest_date"]))
        dates.append(str(second_latest_subquery[0]["latest_date"]))
        print(dates)
        # Perform the necessary filtering and annotation
        qs = (
            queryset.filter(created_at__date__in=dates)
            .values("listing_id", "created_at__date")
            .annotate(cheapest_price=Min("price"))
        )
        print(qs)
        print(len(qs))
        # Retrieve the corresponding rows with the cheapest prices
        result_queryset = queryset.filter(
            created_at__date__in=dates,
            listing_id__in=qs.values_list("listing_id", flat=True),
            price__in=qs.values_list("cheapest_price", flat=True),
        ).order_by("-created_at", "listing_id")
        print(len(result_queryset))
        return result_queryset

Теперь я хочу получить самую дешевую цену для listing_id на последнюю created_at дату, а также вторую последнюю created_at date. Поэтому я запрашиваю даты, помещаю их в список, затем получаю cheapest_price для этих дат (в qs), а затем хочу получить result_queryset со всеми объектами, которые мне нужно вернуть.

Для created_at даты может быть несколько цен на одну и ту же listing_id дату, но мне нужна только cheapest одна (Min()), поэтому я создаю qs подзапрос. Подзапрос qs содержит 60 результатов, что правильно. Но result_queryset содержит 61 результат, и я понял, почему. Потому что он извлекает дополнительный объект, в котором совпадает created_at дата, listing_id совпадает И его price находится внутри qs.values_list("cheapest_price") - только не в комбинации created_at+listing_id+cheapest_price.

Так что если я добавлю в таблицу базы данных одну строку, соответствующую допустимому listing_id, created_at и любому cheapest_price, который находится внутри qs, я получу еще один дополнительный объект. Как это исправить?

thx

Вернуться на верх