Skip to content

Commit

Permalink
solution
Browse files Browse the repository at this point in the history
  • Loading branch information
popeye88 committed Dec 7, 2024
1 parent 93c12eb commit 1996eb0
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 26 deletions.
10 changes: 10 additions & 0 deletions cinema/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from rest_framework.permissions import BasePermission, SAFE_METHODS


class IsAdminOrIfAuthenticatedReadOnly(BasePermission):
def has_permission(self, request, view):
return bool(
request.method in SAFE_METHODS
and request.user
and request.user.is_authenticated
) or (request.user and request.user.is_staff)
78 changes: 62 additions & 16 deletions cinema/views.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,74 @@
from datetime import datetime

from django.db.models import F, Count
from rest_framework import viewsets
from django.db.models import Count, F
from rest_framework.authentication import TokenAuthentication
from rest_framework.mixins import (
CreateModelMixin,
DestroyModelMixin,
ListModelMixin,
RetrieveModelMixin,
UpdateModelMixin,
)
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import GenericViewSet

from cinema.models import Genre, Actor, CinemaHall, Movie, MovieSession, Order

from cinema.models import Actor, CinemaHall, Genre, Movie, MovieSession, Order
from cinema.permissions import IsAdminOrIfAuthenticatedReadOnly
from cinema.serializers import (
GenreSerializer,
ActorSerializer,
CinemaHallSerializer,
MovieSerializer,
MovieSessionSerializer,
MovieSessionListSerializer,
GenreSerializer,
MovieDetailSerializer,
MovieSessionDetailSerializer,
MovieListSerializer,
OrderSerializer,
MovieSerializer,
MovieSessionDetailSerializer,
MovieSessionListSerializer,
MovieSessionSerializer,
OrderListSerializer,
OrderSerializer,
)


class GenreViewSet(viewsets.ModelViewSet):
class GenreViewSet(
ListModelMixin,
CreateModelMixin,
GenericViewSet,
):
queryset = Genre.objects.all()
serializer_class = GenreSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAdminOrIfAuthenticatedReadOnly,)


class ActorViewSet(viewsets.ModelViewSet):
class ActorViewSet(
CreateModelMixin,
ListModelMixin,
GenericViewSet,
):
queryset = Actor.objects.all()
serializer_class = ActorSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAdminOrIfAuthenticatedReadOnly,)


class CinemaHallViewSet(viewsets.ModelViewSet):
class CinemaHallViewSet(ListModelMixin, CreateModelMixin, GenericViewSet):
queryset = CinemaHall.objects.all()
serializer_class = CinemaHallSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAdminOrIfAuthenticatedReadOnly,)


class MovieViewSet(viewsets.ModelViewSet):
class MovieViewSet(
ListModelMixin,
CreateModelMixin,
RetrieveModelMixin,
GenericViewSet,
):
queryset = Movie.objects.prefetch_related("genres", "actors")
serializer_class = MovieSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAdminOrIfAuthenticatedReadOnly,)

@staticmethod
def _params_to_ints(qs):
Expand Down Expand Up @@ -76,7 +106,14 @@ def get_serializer_class(self):
return MovieSerializer


class MovieSessionViewSet(viewsets.ModelViewSet):
class MovieSessionViewSet(
ListModelMixin,
CreateModelMixin,
RetrieveModelMixin,
UpdateModelMixin,
DestroyModelMixin,
GenericViewSet,
):
queryset = (
MovieSession.objects.all()
.select_related("movie", "cinema_hall")
Expand All @@ -87,6 +124,8 @@ class MovieSessionViewSet(viewsets.ModelViewSet):
)
)
serializer_class = MovieSessionSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAdminOrIfAuthenticatedReadOnly,)

def get_queryset(self):
date = self.request.query_params.get("date")
Expand Down Expand Up @@ -118,12 +157,19 @@ class OrderPagination(PageNumberPagination):
max_page_size = 100


class OrderViewSet(viewsets.ModelViewSet):
class OrderViewSet(ListModelMixin, CreateModelMixin, GenericViewSet):
queryset = Order.objects.prefetch_related(
"tickets__movie_session__movie", "tickets__movie_session__cinema_hall"
)
serializer_class = OrderSerializer
pagination_class = OrderPagination
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAdminOrIfAuthenticatedReadOnly,)

def get_permissions(self):
if self.action == "create":
return (IsAuthenticated(),)
return super().get_permissions()

def get_queryset(self):
return Order.objects.filter(user=self.request.user)
Expand Down
8 changes: 2 additions & 6 deletions cinema_service/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/

Expand Down Expand Up @@ -80,7 +79,6 @@

WSGI_APPLICATION = "cinema_service.wsgi.application"


# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases

Expand All @@ -91,7 +89,6 @@
}
}


# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators

Expand Down Expand Up @@ -121,12 +118,11 @@

LANGUAGE_CODE = "en-us"

TIME_ZONE = "UTC"
TIME_ZONE = "Europe/Kiev"

USE_I18N = True

USE_TZ = False

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
Expand Down
3 changes: 2 additions & 1 deletion cinema_service/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from django.contrib import admin
from django.urls import path, include
from django.urls import include, path

urlpatterns = [
path("admin/", admin.site.urls),
path("api/cinema/", include("cinema.urls", namespace="cinema")),
path("api/user/", include("user.urls", namespace="user")),
path("__debug__/", include("debug_toolbar.urls")),
]
34 changes: 33 additions & 1 deletion user/serializers.py
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
# write your code here
from django.contrib.auth import get_user_model
from rest_framework import serializers


class UserSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = (
"id",
"username",
"email",
"password",
"is_staff",
)
read_only_fields = ("id", "is_staff")
extra_kwargs = {
"password": {
"write_only": True,
"min_length": 4,
}
}

def create(self, validated_data):
return get_user_model().objects.create_user(**validated_data)

def update(self, instance, validated_data):
password = validated_data.pop("password", None)
user = super().update(instance, validated_data)

if password:
user.set_password(password)
user.save()
return user
12 changes: 11 additions & 1 deletion user/urls.py
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
# write your code here
from django.urls import path

from user.views import CreateUserView, LoginUserView, ManageUserView

app_name = "user"

urlpatterns = [
path("register/", CreateUserView.as_view(), name="create"),
path("login/", LoginUserView.as_view(), name="login"),
path("me/", ManageUserView.as_view(), name="manage"),
]
25 changes: 24 additions & 1 deletion user/views.py
Original file line number Diff line number Diff line change
@@ -1 +1,24 @@
# write your code here
from rest_framework import generics
from rest_framework.authentication import TokenAuthentication
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.permissions import IsAuthenticated
from rest_framework.settings import api_settings

from user.serializers import UserSerializer


class CreateUserView(generics.CreateAPIView):
serializer_class = UserSerializer


class LoginUserView(ObtainAuthToken):
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES


class ManageUserView(generics.RetrieveUpdateAPIView):
serializer_class = UserSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)

def get_object(self):
return self.request.user

0 comments on commit 1996eb0

Please sign in to comment.