Source code for apps.posts.managers
from typing import TYPE_CHECKING
from django.db import models
from django.db.models import Case, Count, F, FloatField, Q, When
from apps.posts.constants import StatusPostChoice
if TYPE_CHECKING:
from apps.users.models import User
[docs]
class NotDeletedQuerySet(models.QuerySet):
"""
QuerySet that filters out objects which are marked as deleted.
"""
[docs]
def alive(self):
return self.filter(is_deleted=False, is_reported=False, author__is_deleted=False)
[docs]
def most_popular(self):
"""
Order queryset from bigger post like/view quantity
:return:
"""
# Calculate the ratio of likes to view
safe_views = Case(When(views_quantity=0, then=1), default=F("views_quantity"), output_field=FloatField())
likes_to_views_weight = 0.5
likes_weight = 0.5
return (
self.alive()
.annotate(
likes_to_views_ratio=F("likes_quantity") / safe_views,
combined_score=(likes_to_views_weight * F("likes_to_views_ratio"))
+ (likes_weight * F("likes_quantity")),
)
.order_by(
"-combined_score",
"-views_quantity",
)
)
[docs]
def public(self):
return self.most_popular().filter(
visibility=self.model.VisibilityChoices.PUBLIC, status=StatusPostChoice.PUBLISHED
)
[docs]
def private_for_user(self, user: "User"):
return self.most_popular().filter(visibility=self.model.VisibilityChoices.PRIVATE, author=user)
[docs]
def visible_for_user(self, user: "User"):
"""
Get posts that are visible for the given user:
- All public posts
- All private posts authored by the given user
"""
return self.public() | self.private_for_user(user)
[docs]
class NotDeletedManager(models.Manager):
"""
Manager that uses the NotDeletedQuerySet to filter out deleted objects.
"""
[docs]
def get_queryset(self) -> NotDeletedQuerySet:
return NotDeletedQuerySet(self.model, using=self._db).alive()
[docs]
def visible_for_user(self, user):
return self.get_queryset().visible_for_user(user)
[docs]
def public(self):
return self.get_queryset().public()