-
Notifications
You must be signed in to change notification settings - Fork 693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
solution #700
base: master
Are you sure you want to change the base?
solution #700
Changes from 7 commits
a9b56ed
566f7b5
15debdb
25191b4
4b1ee3f
39c00e6
36f1271
e9cb34b
b4e519b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,9 +63,8 @@ def __str__(self): | |
|
||
class Order(models.Model): | ||
created_at = models.DateTimeField(auto_now_add=True) | ||
user = models.ForeignKey( | ||
settings.AUTH_USER_MODEL, on_delete=models.CASCADE | ||
) | ||
user = models.ForeignKey(settings.AUTH_USER_MODEL, | ||
on_delete=models.CASCADE) | ||
|
||
def __str__(self): | ||
return str(self.created_at) | ||
|
@@ -78,9 +77,8 @@ class Ticket(models.Model): | |
movie_session = models.ForeignKey( | ||
MovieSession, on_delete=models.CASCADE, related_name="tickets" | ||
) | ||
order = models.ForeignKey( | ||
Order, on_delete=models.CASCADE, related_name="tickets" | ||
) | ||
order = models.ForeignKey(Order, on_delete=models.CASCADE, | ||
related_name="tickets") | ||
row = models.IntegerField() | ||
seat = models.IntegerField() | ||
|
||
|
@@ -122,8 +120,8 @@ def save( | |
) | ||
|
||
def __str__(self): | ||
return (f"{str(self.movie_session)} " | ||
f"(row: {self.row}, seat: {self.seat})") | ||
return f"{str(self.movie_session)} "\ | ||
f"(row: {self.row}, seat: {self.seat})" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a syntax error in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😭 whyyyy There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a syntax error in the |
||
|
||
class Meta: | ||
unique_together = ("movie_session", "row", "seat") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
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) | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,9 +37,9 @@ class Meta: | |
|
||
|
||
class MovieListSerializer(MovieSerializer): | ||
genres = serializers.SlugRelatedField( | ||
many=True, read_only=True, slug_field="name" | ||
) | ||
genres = serializers.SlugRelatedField(many=True, | ||
read_only=True, | ||
slug_field="name") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💀 |
||
actors = serializers.SlugRelatedField( | ||
many=True, read_only=True, slug_field="full_name" | ||
) | ||
|
@@ -51,7 +51,8 @@ class MovieDetailSerializer(MovieSerializer): | |
|
||
class Meta: | ||
model = Movie | ||
fields = ("id", "title", "description", "duration", "genres", "actors") | ||
fields = ("id", "title", "description", | ||
"duration", "genres", "actors") | ||
|
||
|
||
class MovieSessionSerializer(serializers.ModelSerializer): | ||
|
@@ -61,10 +62,10 @@ class Meta: | |
|
||
|
||
class MovieSessionListSerializer(MovieSessionSerializer): | ||
movie_title = serializers.CharField(source="movie.title", read_only=True) | ||
cinema_hall_name = serializers.CharField( | ||
source="cinema_hall.name", read_only=True | ||
) | ||
movie_title = serializers.CharField(source="movie.title", | ||
read_only=True) | ||
cinema_hall_name = serializers.CharField(source="cinema_hall.name", | ||
read_only=True) | ||
cinema_hall_capacity = serializers.IntegerField( | ||
source="cinema_hall.capacity", read_only=True | ||
) | ||
|
@@ -85,9 +86,8 @@ class Meta: | |
class TicketSerializer(serializers.ModelSerializer): | ||
def validate(self, attrs): | ||
data = super(TicketSerializer, self).validate(attrs=attrs) | ||
Ticket.validate_ticket( | ||
attrs["row"], attrs["seat"], attrs["movie_session"] | ||
) | ||
Ticket.validate_ticket(attrs["row"], attrs["seat"], | ||
attrs["movie_session"]) | ||
Comment on lines
+91
to
+92
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Comment on lines
+91
to
+92
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
return data | ||
|
||
class Meta: | ||
|
@@ -96,7 +96,8 @@ class Meta: | |
|
||
|
||
class TicketListSerializer(TicketSerializer): | ||
movie_session = MovieSessionListSerializer(many=False, read_only=True) | ||
movie_session = MovieSessionListSerializer(many=False, | ||
read_only=True) | ||
|
||
|
||
class TicketSeatsSerializer(TicketSerializer): | ||
|
@@ -108,9 +109,8 @@ class Meta: | |
class MovieSessionDetailSerializer(MovieSessionSerializer): | ||
movie = MovieListSerializer(many=False, read_only=True) | ||
cinema_hall = CinemaHallSerializer(many=False, read_only=True) | ||
taken_places = TicketSeatsSerializer( | ||
source="tickets", many=True, read_only=True | ||
) | ||
taken_places = TicketSeatsSerializer(source="tickets", many=True, | ||
read_only=True) | ||
|
||
class Meta: | ||
model = MovieSession | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,9 +54,7 @@ def test_get_movies(self): | |
def test_retrieve_movie(self): | ||
movie = sample_movie() | ||
movie.genres.add(Genre.objects.create(name="Genre")) | ||
movie.actors.add( | ||
Actor.objects.create(first_name="Actor", last_name="Last") | ||
) | ||
movie.actors.add(Actor.objects.create(first_name="Actor", last_name="Last")) | ||
|
||
url = detail_url(movie.id) | ||
response = self.client.get(url) | ||
|
@@ -114,16 +112,12 @@ def test_put_movie(self): | |
} | ||
|
||
response = self.client.put(url, payload) | ||
self.assertEqual( | ||
response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED | ||
) | ||
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
||
def test_delete_movie(self): | ||
movie = sample_movie() | ||
|
||
url = detail_url(movie.id) | ||
response = self.client.delete(url) | ||
|
||
self.assertEqual( | ||
response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED | ||
) | ||
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree, usually delete methor returns There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,8 @@ | |
|
||
# SECURITY WARNING: keep the secret key used in production secret! | ||
SECRET_KEY = ( | ||
"django-insecure-6vubhk2$++agnctay_4pxy_8cq)mosmn(*-#2b^v4cgsh-^!i3" | ||
"django-insecure-6vubhk2$++agnctay_4" | ||
"pxy_8cq)mosmn(*-#2b^v4cgsh-^!i3" | ||
Comment on lines
+24
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Comment on lines
+24
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
) | ||
|
||
# SECURITY WARNING: don't run with debug turned on in production! | ||
|
@@ -125,7 +126,7 @@ | |
|
||
USE_I18N = True | ||
|
||
USE_TZ = False | ||
USE_TZ = True | ||
|
||
|
||
# Static files (CSS, JavaScript, Images) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,35 @@ | ||
# 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 = ( | ||
"id", | ||
"is_staff", | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
extra_kwargs = {"password": {"write_only": True, "min_length": 5}} | ||
|
||
def create(self, validated_data): | ||
"""create user with encrypted password""" | ||
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,9 +59,7 @@ def test_password_too_short(self): | |
res = self.client.post(CREATE_USER_URL, payload) | ||
|
||
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST) | ||
user_exists = ( | ||
get_user_model().objects.filter(email=payload["email"]).exists() | ||
) | ||
user_exists = get_user_model().objects.filter(email=payload["email"]).exists() | ||
self.assertFalse(user_exists) | ||
|
||
def test_create_token_for_user(self): | ||
|
@@ -79,9 +77,7 @@ def test_create_token_for_user(self): | |
|
||
def test_create_token_invalid_credentials(self): | ||
"""Test that token is not created if invalid credentials are given""" | ||
create_user( | ||
username="user12345", email="[email protected]", password="test123" | ||
) | ||
create_user(username="user12345", email="[email protected]", password="test123") | ||
payload = { | ||
"username": "user12345", | ||
"email": "[email protected]", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,14 @@ | ||
# 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"), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,25 @@ | ||
# 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?