feat: added comments cruds

This commit is contained in:
ITQ
2025-01-25 22:01:36 +03:00
parent 974bb1acb4
commit 69fa312201
3 changed files with 208 additions and 2 deletions
+34
View File
@@ -1,9 +1,11 @@
import datetime
import uuid import uuid
from typing import ClassVar from typing import ClassVar
from ninja import ModelSchema, Schema from ninja import ModelSchema, Schema
from pydantic import Field, StrictInt from pydantic import Field, StrictInt
from apps.promo.models import PromocodeComment
from apps.user.models import User from apps.user.models import User
@@ -96,3 +98,35 @@ class PromocodeLikeOut(Schema):
class PromocodeRemoveLikeOut(Schema): class PromocodeRemoveLikeOut(Schema):
status: str = "ok" status: str = "ok"
class PromocodeCommentsFilters(Schema):
limit: int = Field(10, gt=0, description="Limit must be greater than 0")
offset: int = Field(
0, ge=0, description="Offset must be greater than or equal to 0"
)
class CommentIn(ModelSchema):
class Meta:
model = PromocodeComment
fields: ClassVar[list[str]] = [
PromocodeComment.text.field.name
]
class CommentAuthor(Schema):
name: str
surname: str
avatar_url: str | None
class CommentOut(Schema):
id: uuid.UUID
text: str
date: datetime.datetime
author: CommentAuthor
class CommentDeletedOut(Schema):
status: str = "ok"
+14 -1
View File
@@ -1,5 +1,5 @@
from api.v1.user import schemas from api.v1.user import schemas
from apps.promo.models import Promocode from apps.promo.models import Promocode, PromocodeComment
from apps.user.models import User from apps.user.models import User
@@ -29,3 +29,16 @@ def map_promocode_to_schema(promocode: Promocode) -> schemas.PromocodeViewOut:
comment_count=promocode.comment_count, comment_count=promocode.comment_count,
active=promocode.active, active=promocode.active,
) )
def map_comment_to_schema(comment: PromocodeComment) -> schemas.CommentOut:
return schemas.CommentOut(
id=comment.id,
text=comment.text,
date=comment.date,
author=schemas.CommentAuthor(
name=comment.author.name,
surname=comment.author.surname,
avatar_url=comment.author.avatar_url
)
)
+160 -1
View File
@@ -9,7 +9,12 @@ from ninja.errors import AuthenticationError, HttpError
from api.v1 import schemas as global_schemas from api.v1 import schemas as global_schemas
from api.v1.auth import UserAuth from api.v1.auth import UserAuth
from api.v1.user import schemas, utils from api.v1.user import schemas, utils
from apps.promo.models import Promocode, PromocodeActivation, PromocodeLike from apps.promo.models import (
Promocode,
PromocodeActivation,
PromocodeComment,
PromocodeLike,
)
from apps.user.models import User from apps.user.models import User
from config.errors import UniqueConstraintError from config.errors import UniqueConstraintError
@@ -268,3 +273,157 @@ def delete_like(
).delete() ).delete()
return status.OK, schemas.PromocodeLikeOut() return status.OK, schemas.PromocodeLikeOut()
@router.post(
"/promo/{promocode_id}/comments",
auth=UserAuth(),
response={
status.CREATED: schemas.CommentOut,
status.BAD_REQUEST: global_schemas.BadRequestError,
},
)
def add_comment(
request: HttpRequest, promocode_id: str, comment: schemas.CommentIn
) -> tuple[int, schemas.CommentOut]:
user: User = request.auth
promocodes = Promocode.objects.filter(id=promocode_id)
if not promocodes.exists():
raise HttpError(status.NOT_FOUND, status.NOT_FOUND.phrase)
comment_obj = PromocodeComment(
promocode=promocodes.first(), author=user, **comment.dict()
)
comment_obj.save()
return status.CREATED, utils.map_comment_to_schema(comment_obj)
@router.get(
"/promo/{promocode_id}/comments",
auth=UserAuth(),
response={
status.OK: list[schemas.CommentOut],
status.NOT_FOUND: global_schemas.NotFoundError,
},
exclude_none=True,
)
def list_comments(
request: HttpRequest,
filters: Query[schemas.PromocodeCommentsFilters],
promocode_id: str,
) -> tuple[int, schemas.CommentOut]:
promocodes = Promocode.objects.filter(id=promocode_id)
if not promocodes.exists():
raise HttpError(status.NOT_FOUND, status.NOT_FOUND.phrase)
promocodes = promocodes.prefetch_related("comments", "comments__author")
comments = promocodes.first().comments.all()
comments = comments[filters.offset : filters.offset + filters.limit]
return status.OK, [
utils.map_comment_to_schema(comment) for comment in comments
]
@router.get(
"/promo/{promocode_id}/comments/{comment_id}",
auth=UserAuth(),
response={
status.OK: schemas.CommentOut,
status.NOT_FOUND: global_schemas.NotFoundError,
},
exclude_none=True,
)
def get_comment(
request: HttpRequest, promocode_id: str, comment_id: str
) -> tuple[int, schemas.CommentOut]:
commnets = PromocodeComment.objects.filter(
id=comment_id, promocode_id=promocode_id
)
if not commnets.exists():
raise HttpError(status.NOT_FOUND, status.NOT_FOUND.phrase)
comment = commnets.select_related("author").first()
return status.OK, utils.map_comment_to_schema(comment)
@router.put(
"/promo/{promocode_id}/comments/{comment_id}",
auth=UserAuth(),
response={
status.OK: schemas.CommentOut,
status.BAD_REQUEST: global_schemas.BadRequestError,
},
)
def update_comment(
request: HttpRequest,
promocode_id: str,
comment_id: str,
comment: schemas.CommentIn,
) -> tuple[int, schemas.CommentOut]:
user: User = request.auth
commnets = PromocodeComment.objects.filter(
id=comment_id, promocode_id=promocode_id
)
if not commnets.exists():
raise HttpError(status.NOT_FOUND, status.NOT_FOUND.phrase)
comments = commnets.select_related("author").filter(author=user)
if not comments.exists():
raise HttpError(status.FORBIDDEN, status.FORBIDDEN.phrase)
comment_obj = comments.first()
put_data = comment.dict()
for field, value in put_data.items():
setattr(comment_obj, field, value)
comment_obj.save()
return status.OK, utils.map_comment_to_schema(comment_obj)
@router.delete(
"/promo/{promocode_id}/comments/{comment_id}",
auth=UserAuth(),
response={
status.OK: schemas.CommentDeletedOut,
status.BAD_REQUEST: global_schemas.BadRequestError,
status.NOT_FOUND: global_schemas.NotFoundError,
},
)
def delete_comment(
request: HttpRequest,
promocode_id: str,
comment_id: str,
) -> tuple[int, schemas.CommentOut]:
user: User = request.auth
commnets = PromocodeComment.objects.filter(
id=comment_id, promocode_id=promocode_id
)
if not commnets.exists():
raise HttpError(status.NOT_FOUND, status.NOT_FOUND.phrase)
comments = commnets.select_related("author").filter(author=user)
if not comments.exists():
raise HttpError(status.FORBIDDEN, status.FORBIDDEN.phrase)
comment_obj = comments.first()
comment_obj.delete()
return status.OK, schemas.CommentDeletedOut()