Упорядочение набора запросов на основе условия из полей в разных таблицах
У меня есть несколько ресурсов, на которые пользователь может подписаться, чтобы получить дополнительные преимущества. Моя задача состоит в том, чтобы отсортировать их так, чтобы ресурсы с подпиской были на первом месте, а остальные следовали за ними.
Изначально ресурсы хранились следующим образом.
from django.db import models
from django.utils import timezone
class Entity(models.Model):
has_subscription = models.BooleanField()
created_at = models.DateTimeField(default=timezone.now)
# other fields
и я бы отсортировал их следующим образом,
Entity.objects.all()order_by("-has_subscription", "-created_at")
который сработал.
Я решил перейти к другому способу хранения, который бы способствовал подписке, ограниченной по времени. Я пришел к следующему варианту.
from django.db import models
from django.utils import timezone
class Entity(models.Model):
created_at = models.DateTimeField(default=timezone.now)
@property
def has_active_subscription(self):
if (
self.entity_subscriptions.filter(
start_date__lte=timezone.now(), end_date__gte=timezone.now()
).count()
> 0
):
return True
return False
class Subscriptions(model.Model):
entity = models.ForeignKey(
Entity,
on_delete=models.CASCADE,
related_name="entity_subscriptions",
related_query_name="entity_subscription",
)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
Как я могу отсортировать набор запросов таким образом, чтобы ресурсы с подпиской были на первом месте.
После долгих поисков, следующее решение сработало для меня.
from django.db.models import Case, When, Q
from django.utils import timezone
Entity.objects.annotate(
active_sub=Case(
When(
Q(
entity_subscription__start_date__lte=timezone.now(),
entity_subscription__end_date__gte=timezone.now(),
),
then=True,
),
default=False,
)
).order_by("-active_sub", "-created_at")