feat(backend): add blog featured image endpoints
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-09 08:53:30 +03:30
parent 954e78d0cb
commit a8b992279d

View File

@@ -94,6 +94,18 @@ def _validate_asset_file(file: UploadedFile) -> str | None:
return None return None
def _validate_featured_image(file: UploadedFile) -> str | None:
suffix = Path(file.name).suffix.lower()
content_type = (file.content_type or mimetypes.guess_type(file.name)[0] or "").lower()
if not content_type.startswith("image/") and suffix not in IMAGE_EXTENSIONS:
return "Featured image must be an image file."
image_max_size_mb = getattr(settings, "BLOG_IMAGE_ASSET_MAX_SIZE_MB", 10)
if file.size > image_max_size_mb * 1024 * 1024:
return f"Featured image size must be less than {image_max_size_mb}MB."
return None
def _apply_post_payload(post: Post, data: PostCreateSchema, *, user, allow_status: bool = False) -> Post: def _apply_post_payload(post: Post, data: PostCreateSchema, *, user, allow_status: bool = False) -> Post:
payload = data.dict(exclude_unset=True) payload = data.dict(exclude_unset=True)
tag_ids = payload.pop("tag_ids", None) tag_ids = payload.pop("tag_ids", None)
@@ -190,6 +202,32 @@ def update_admin_post(request, post_id: int, data: PostCreateSchema):
return 400, {"error": "Failed to update post", "details": str(exc)} return 400, {"error": "Failed to update post", "details": str(exc)}
@blog_router.post("/admin/posts/{post_id}/featured-image", response={200: PostDetailSchema, 400: ErrorSchema, 403: ErrorSchema}, auth=jwt_auth)
def upload_post_featured_image(request, post_id: int, file: UploadedFile = File(...)):
post = get_object_or_404(Post, id=post_id)
if not can_edit_post(request.auth, post):
return 403, {"error": "Permission denied"}
error = _validate_featured_image(file)
if error:
return 400, {"error": error}
post.featured_image = file
post.save(update_fields=["featured_image", "updated_at"])
return 200, _post_queryset().get(pk=post.pk)
@blog_router.delete("/admin/posts/{post_id}/featured-image", response={200: PostDetailSchema, 403: ErrorSchema}, auth=jwt_auth)
def delete_post_featured_image(request, post_id: int):
post = get_object_or_404(Post, id=post_id)
if not can_edit_post(request.auth, post):
return 403, {"error": "Permission denied"}
post.featured_image = None
post.save(update_fields=["featured_image", "updated_at"])
return 200, _post_queryset().get(pk=post.pk)
@blog_router.post("/admin/posts/{post_id}/submit", response={200: PostDetailSchema, 403: ErrorSchema}, auth=jwt_auth) @blog_router.post("/admin/posts/{post_id}/submit", response={200: PostDetailSchema, 403: ErrorSchema}, auth=jwt_auth)
def submit_post_for_review(request, post_id: int): def submit_post_for_review(request, post_id: int):
post = get_object_or_404(Post, id=post_id) post = get_object_or_404(Post, id=post_id)