Возможно ли это в Django ORM? Я хочу сделать запрос на обратный внешний ключ отношения ship. Мне нужно довольно много запросов из базы данных

Что у меня есть?

У меня есть модели, как показано ниже.

class Product(models.Model):
    title = models.CharField(max_length=500)
    timestamp = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)


class Price(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    amount = models.DecimalField(decimal_places=2, max_digits=6)
    timestamp = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

В основном я хочу отслеживать цену продукта. Каждый товар имеет одну текущую цену и может иметь историю предыдущих цен.

Мне нужно довольно много вещей.

Что мне нужно?

Мне нужны товары с ценами, но упорядоченные по цене.

Что я сделал?

Я сделал следующее.

queryset = Product.objects.all()
queryset = queryset.prefetch_related(
    Prefetch("price_set", queryset=Price.objects.all())
)
queryset = queryset.order_by("price__amount")

Правильно ли это? Или есть более эффективный способ сделать это?

Что мне нужно?

Мне нужно отсортировать товары по количеству изменений цены. Например, если за последние 10 дней цена товара A изменилась 5 раз, а цена товара B изменилась 6 раз за последние 10 дней, то товар B должен быть первым, а товар A - вторым в наборе запросов?

Я понятия не имею, как это сделать.

Пожалуйста, помогите мне с этими двумя вопросами. Любая помощь будет высоко оценена. Спасибо.

То, что я пробовал, описано выше.

Вы можете сделать это, добавив соответствующие изменения цены в указанном временном интервале, а затем отсортировать набор запросов на основе этого подсчета.

from django.db.models import Count, Q
from datetime import timedelta


time_frame = timezone.now() - timedelta(days=10)


queryset = Product.objects.annotate(
    price_changes_count=Count(
        "price",
        filter=Q(price__timestamp__gte=time_frame)
    )
)


queryset = queryset.order_by("-price_changes_count")
Вернуться на верх