feat: added competition logic

This commit is contained in:
Андрей Сумин
2025-03-01 02:33:06 +03:00
parent 930fb23bbc
commit 999f5b0690
9 changed files with 167 additions and 19 deletions
+22 -2
View File
@@ -1,8 +1,9 @@
from typing import Literal
from uuid import UUID
from ninja import ModelSchema
from ninja import ModelSchema, Schema
from apps.competition.models import Competition
from apps.competition.models import Competition, State
class CompetitionOut(ModelSchema):
@@ -12,12 +13,31 @@ class CompetitionOut(ModelSchema):
model = Competition
fields = "__all__"
class StateOut(ModelSchema):
class Meta:
model = State
fields = (
"state",
)
class StateIn(Schema):
state: Literal["started", "not_started", "finished"]
class CompetitionListInstanceOut(ModelSchema):
id: UUID
is_participating: bool
completed: bool
@staticmethod
def resolve_is_participating(self, context):
user = context["request"].auth
return self.participants.filter(id=user.id).exists()
@staticmethod
def resolve_completed(self, context):
user = context["request"].auth
return State.objects.filter(competition=self, user=user, state="finished").exists()
class Meta:
model = Competition
fields = (
+37 -6
View File
@@ -1,12 +1,14 @@
from http import HTTPStatus as status
from typing import Literal
from uuid import UUID
from django.http import HttpRequest
from django.shortcuts import get_object_or_404
from django.http import HttpRequest, Http404
from ninja import Router
import api.v1.schemas as global_schemas
from api.v1.auth import BearerAuth
from api.v1.competition import schemas
from apps.competition.models import Competition, State
router = Router(tags=["competition"])
@@ -18,11 +20,12 @@ router = Router(tags=["competition"])
status.BAD_REQUEST: global_schemas.BadRequestError,
status.UNAUTHORIZED: global_schemas.UnauthorizedError,
},
auth=BearerAuth(),
)
def get_competition(
request: HttpRequest, competition_id: UUID
) -> tuple[status, schemas.CompetitionOut]: ...
) -> tuple[status, schemas.CompetitionOut]:
competition = get_object_or_404(Competition, id=competition_id)
return status.OK, competition
@router.get(
@@ -32,8 +35,36 @@ def get_competition(
status.BAD_REQUEST: global_schemas.BadRequestError,
status.UNAUTHORIZED: global_schemas.UnauthorizedError,
},
auth=BearerAuth(),
)
def list_competitions(
request: HttpRequest, is_participating: bool
) -> tuple[status, list[schemas.CompetitionListInstanceOut]]: ...
) -> tuple[status, list[schemas.CompetitionListInstanceOut]]:
user = request.auth
if is_participating:
competitions = Competition.objects.filter(participants=user)
else:
competitions = Competition.objects.exclude(participants=user)
return status.OK, competitions
@router.post(
"competitions/{competition_id}/state",
response={
status.OK: schemas.StateOut,
status.BAD_REQUEST: global_schemas.BadRequestError,
status.UNAUTHORIZED: global_schemas.UnauthorizedError,
}
)
def change_competition_state(
request: HttpRequest,
competition_id: UUID,
state: schemas.StateIn,
) -> tuple[status, schemas.StateOut]:
user = request.auth
competition = get_object_or_404(Competition, id=competition_id)
state_obj, _ = State.objects.update_or_create(
user=user,
competition=competition,
state=state.state
)
return status.OK, schemas.StateOut.from_orm(state_obj)
+2
View File
@@ -3,6 +3,7 @@ from functools import partial
from ninja import NinjaAPI
from api.v1 import handlers
from api.v1.auth import BearerAuth
from api.v1.competition.views import router as competition_router
from api.v1.ping.views import router as ping_router
from api.v1.user.views import router as user_router
@@ -12,6 +13,7 @@ router = NinjaAPI(
version="1",
description="API docs for DataRush",
openapi_url="/docs/openapi.json",
auth=BearerAuth()
)