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
from typing import ClassVar
from ninja import ModelSchema, Schema
from pydantic import Field, StrictInt
from apps.promo.models import PromocodeComment
from apps.user.models import User
@@ -96,3 +98,35 @@ class PromocodeLikeOut(Schema):
class PromocodeRemoveLikeOut(Schema):
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 apps.promo.models import Promocode
from apps.promo.models import Promocode, PromocodeComment
from apps.user.models import User
@@ -29,3 +29,16 @@ def map_promocode_to_schema(promocode: Promocode) -> schemas.PromocodeViewOut:
comment_count=promocode.comment_count,
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.auth import UserAuth
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 config.errors import UniqueConstraintError
@@ -268,3 +273,157 @@ def delete_like(
).delete()
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()