Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,6 @@ marimo/_lsp/
__marimo__/

media/

logs/
*.log
108 changes: 91 additions & 17 deletions backend/api/v1/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import logging

from django_filters.rest_framework import DjangoFilterBackend
from drf_spectacular.utils import extend_schema
from rest_framework import filters, permissions, viewsets
from rest_framework import filters, permissions, serializers, viewsets

from api.v1.permissions import IsAdminOrReadOnly, IsOwnerOrAdmin
from api.v1.serializers import (
Expand All @@ -14,6 +16,8 @@
)
from rooms.models import Booking, Room, RoomImage, RoomType

logger = logging.getLogger("rooms")


@extend_schema(tags=["RoomType"], summary="Управление типами номеров")
class RoomTypeViewSet(viewsets.ModelViewSet):
Expand All @@ -28,6 +32,15 @@ class RoomTypeViewSet(viewsets.ModelViewSet):
filter_backends = (filters.OrderingFilter,)
ordering_fields = ("name",)

def get_queryset(self):
try:
queryset = RoomType.objects.all()
logger.info(f"Запрошены типы номеров, всего найдено: {queryset.count()}")
return queryset
except Exception as error:
logger.debug(f"Ошибка при получении типов номеров: {error}", exc_info=True)
return RoomType.objects.none()


@extend_schema(tags=["RoomImage"])
class RoomImageViewSet(viewsets.ModelViewSet):
Expand All @@ -36,9 +49,21 @@ class RoomImageViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAdminUser,)

def get_serializer_class(self):
if self.action in ["list", "retrieve"]:
return RoomImageReadSerializer
return RoomImageWriteSerializer
try:
if self.action in ["list", "retrieve"]:
logger.debug(
f"Используется RoomImageReadSerializer для действия {self.action}"
)
return RoomImageReadSerializer
logger.debug(
f"Используется RoomImageWriteSerializer для действия {self.action}"
)
return RoomImageWriteSerializer
except Exception as error:
logger.error(
f"Ошибка при выборе сериализатора для RoomImage: {error}", exc_info=True
)
return RoomImageWriteSerializer


@extend_schema(
Expand Down Expand Up @@ -66,14 +91,31 @@ class RoomViewSet(viewsets.ModelViewSet):
)

def get_serializer_class(self):
if self.action in ["list", "retrieve"]:
return RoomReadSerializer
return RoomWriteSerializer
try:
if self.action in ["list", "retrieve"]:
logger.debug(
f"Используется RoomReadSerializer для действия {self.action}"
)
return RoomReadSerializer
logger.debug(f"Используется RoomWriteSerializer для действия {self.action}")
return RoomWriteSerializer
except Exception as error:
logger.error(
f"Ошибка при выборе сериализатора для Room: {error}", exc_info=True
)
return RoomWriteSerializer

def get_queryset(self):
if self.request.user.is_staff or self.request.user.is_superuser:
return Room.objects.all()
return Room.objects.filter(is_available=True)
try:
if self.request.user.is_staff or self.request.user.is_superuser:
queryset = Room.objects.all()
else:
queryset = Room.objects.filter(is_available=True)
logger.debug(f"Запрошены номера, всего найдено: {queryset.count()}")
return queryset
except Exception as error:
logger.error(f"Ошибка при получении списка номеров: {error}", exc_info=True)
return Room.objects.none()


@extend_schema(tags=["Booking"], summary="Работа с бронированиями")
Expand All @@ -92,14 +134,46 @@ class BookingViewSet(viewsets.ModelViewSet):
ordering_fields = ("status", "check_in", "check_out")

def get_serializer_class(self):
if self.action in ["list", "retrieve"]:
return BookingReadSerializer
return BookingWriteSerializer
try:
if self.action in ["list", "retrieve"]:
logger.debug(
f"Используется BookingReadSerializer для действия {self.action}"
)
return BookingReadSerializer
logger.debug(
f"Используется BookingWriteSerializer для действия {self.action}"
)
return BookingWriteSerializer
except Exception as error:
logger.error(
f"Ошибка при выборе сериализатора для Booking: {error}", exc_info=True
)
return BookingWriteSerializer

def get_queryset(self):
if self.request.user.is_staff or self.request.user.is_superuser:
return Booking.objects.all()
return Booking.objects.filter(user=self.request.user)
try:
if self.request.user.is_staff or self.request.user.is_superuser:
queryset = Booking.objects.all()
else:
queryset = Booking.objects.filter(user=self.request.user)
logger.debug(
f"Запрошены бронирования пользователем: {self.request.user}, найдеено бронирований: {queryset.count()}"
)
return queryset
except Exception as error:
logger.error(
f"Ошибка при получении списка бронирований: {error}", exc_info=True
)
return Booking.objects.none()

def perform_create(self, serializer):
serializer.save(user=self.request.user)
try:
serializer.save(user=self.request.user)
logger.info(
f"Пользователь {self.request.user} создал бронирование для номера {serializer.instance.room}"
)
except Exception as error:
logger.error(f"Не удалось создать бронирование: {error}", exc_info=True)
raise serializers.ValidationError(
{"error": "Не Удалось создать бронирование"}
)
35 changes: 35 additions & 0 deletions backend/bookinn/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,41 @@

BASE_DIR = Path(__file__).resolve().parent.parent

LOG_DIR = Path(BASE_DIR / "logs")
LOG_DIR.mkdir(exist_ok=True)

LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"verbose": {
"format": "{levelname} {asctime} {module} {message}",
"style": "{",
},
"simple": {
"format": "{levelname} {message}",
"style": "{",
},
},
"handlers": {
"console": {
"level": "DEBUG",
"class": "logging.StreamHandler",
"formatter": "verbose",
},
"file": {
"level": "INFO",
"class": "logging.FileHandler",
"filename": LOG_DIR / "django.log",
"formatter": "verbose",
},
},
"loggers": {
"django": {"handlers": ["console", "file"], "level": "INFO", "propagate": True},
"rooms": {"handlers": ["console", "file"], "level": "DEBUG", "propagate": False},
},
}


load_dotenv()
SECRET_KEY = os.getenv("SECRET_KEY", default="supersecretkey")
Expand Down
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ djangorestframework_simplejwt==5.5.1
djoser==2.3.3
drf-spectacular==0.29.0
flake8==7.3.0
flake8-isort==6.1.2
idna==3.11
importlib_metadata==8.7.0
inflection==0.5.1
isort==6.1.0
jsonschema==4.25.1
jsonschema-specifications==2025.9.1
Markdown==3.9
Expand All @@ -27,6 +29,7 @@ packaging==25.0
pathspec==0.12.1
pillow==11.3.0
platformdirs==4.4.0
psycopg2-binary==2.9.11
pycodestyle==2.14.0
pycparser==2.23
pyflakes==3.4.0
Expand Down