feat(blog): add recommended posts endpoint
Some checks failed
Backend CI/CD / test (push) Has been cancelled
Backend CI/CD / deploy (push) Has been cancelled

This commit is contained in:
2026-06-10 11:55:44 +03:30
parent a8b992279d
commit 4039be0187

View File

@@ -357,6 +357,47 @@ def list_posts(
return list(queryset[offset : offset + limit]) return list(queryset[offset : offset + limit])
@blog_router.get("/posts/{slug}/recommended", response=List[PostListSchema])
def recommended_posts(request, slug: str, limit: int = Query(3, ge=1, le=12)):
post = get_object_or_404(
Post.objects.select_related("category").prefetch_related("tags"),
slug=slug,
status=Post.StatusChoices.PUBLISHED,
)
tag_ids = list(post.tags.values_list("id", flat=True))
selected = []
seen_ids = {post.id}
def append_posts(queryset):
remaining = limit - len(selected)
if remaining <= 0:
return
for candidate in queryset.exclude(id__in=seen_ids)[:remaining]:
selected.append(candidate)
seen_ids.add(candidate.id)
if tag_ids:
append_posts(
_published_queryset()
.filter(tags__id__in=tag_ids)
.annotate(shared_tags=Count("tags", filter=Q(tags__id__in=tag_ids), distinct=True))
.order_by("-shared_tags", "-published_at", "-created_at")
.distinct()
)
if len(selected) < limit and post.category_id:
append_posts(
_published_queryset()
.filter(category_id=post.category_id)
.order_by("-published_at", "-created_at")
)
if len(selected) < limit:
append_posts(_published_queryset().order_by("-published_at", "-created_at"))
return selected
@blog_router.get("/posts/{slug}", response=PostDetailSchema) @blog_router.get("/posts/{slug}", response=PostDetailSchema)
def get_post(request, slug: str): def get_post(request, slug: str):
return get_object_or_404(_published_queryset(), slug=slug) return get_object_or_404(_published_queryset(), slug=slug)