Hotfix before deadline

This commit is contained in:
ITQ
2024-03-04 23:21:51 +03:00
parent 9a4b18b4c1
commit 79f0aaaaa6
9 changed files with 40 additions and 29 deletions
+8 -6
View File
@@ -11,20 +11,22 @@ class CountryListApiView(ListAPIView):
serializer_class = CountrySerializer serializer_class = CountrySerializer
def filter_queryset(self, queryset): def filter_queryset(self, queryset):
regions = self.request.query_params.get("region") regions = self.request.query_params.getlist("region")
if regions == [""]:
return queryset
if regions: if regions:
regions_list = regions.split(",")
invalid_regions = [ invalid_regions = [
region region for region in regions if region not in settings.REGIONS
for region in regions_list
if region not in settings.REGIONS
] ]
if invalid_regions: if invalid_regions:
invalid_regions_str = ", ".join(invalid_regions) invalid_regions_str = ", ".join(invalid_regions)
error_message = f"Invalid region(s): {invalid_regions_str}" error_message = f"Invalid region(s): {invalid_regions_str}"
raise ValidationError(error_message) raise ValidationError(error_message)
queryset = queryset.filter(region__in=regions_list) queryset = queryset.filter(region__in=regions)
return queryset return queryset
+7 -4
View File
@@ -1,11 +1,14 @@
from rest_framework import status from rest_framework import status
from rest_framework.exceptions import APIException
from rest_framework.permissions import BasePermission from rest_framework.permissions import BasePermission
class CanAccessPost(BasePermission): class CustomForbidden(APIException):
message = "You do not have permission to access this post."
status_code = status.HTTP_404_NOT_FOUND status_code = status.HTTP_404_NOT_FOUND
default_detail = "You dont have access to view this post."
class CanAccessPost(BasePermission):
def has_object_permission(self, request, view, obj): def has_object_permission(self, request, view, obj):
if ( if (
obj.author.isPublic obj.author.isPublic
@@ -14,7 +17,7 @@ class CanAccessPost(BasePermission):
): ):
return True return True
return False raise CustomForbidden
class CanAccessFeed(BasePermission): class CanAccessFeed(BasePermission):
@@ -29,4 +32,4 @@ class CanAccessFeed(BasePermission):
): ):
return True return True
return False raise CustomForbidden
+8 -1
View File
@@ -6,7 +6,7 @@ from api.posts.models import Post
class PostSerializer(serializers.ModelSerializer): class PostSerializer(serializers.ModelSerializer):
# ruff: noqa: N815 # ruff: noqa: N815
author = serializers.ReadOnlyField(source="author.username") author = serializers.SerializerMethodField()
likesCount = serializers.SerializerMethodField() likesCount = serializers.SerializerMethodField()
dislikesCount = serializers.SerializerMethodField() dislikesCount = serializers.SerializerMethodField()
@@ -30,7 +30,14 @@ class PostSerializer(serializers.ModelSerializer):
def get_dislikesCount(self, obj): def get_dislikesCount(self, obj):
return obj.dislikes.count() return obj.dislikes.count()
def get_author(self, obj):
return obj.author.login
def validate_tags(self, value): def validate_tags(self, value):
if not isinstance(value, list):
error = "Tags must be provided as a list."
raise serializers.ValidationError(error)
for tag in value: for tag in value:
if len(tag) > settings.MAX_TAG_LENGTH: if len(tag) > settings.MAX_TAG_LENGTH:
error = "Each tag must be 20 characters or fewer." error = "Each tag must be 20 characters or fewer."
+2 -2
View File
@@ -4,12 +4,12 @@ import api.posts.views
urlpatterns = [ urlpatterns = [
path( path(
"/create", "/new",
api.posts.views.CreatePostApiView.as_view(), api.posts.views.CreatePostApiView.as_view(),
name="create-post", name="create-post",
), ),
path( path(
"/<str:post_id>", "/<uuid:post_id>",
api.posts.views.PostDetailApiView.as_view(), api.posts.views.PostDetailApiView.as_view(),
name="post-detail", name="post-detail",
), ),
+7 -5
View File
@@ -18,7 +18,7 @@ class CreatePostApiView(APIView):
serializer = PostSerializer(data=request.data) serializer = PostSerializer(data=request.data)
if serializer.is_valid(): if serializer.is_valid():
serializer.save(author=request.user) serializer.save(author=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.data, status=status.HTTP_200_OK)
raise ValidationError(serializer.errors) raise ValidationError(serializer.errors)
@@ -52,7 +52,9 @@ class MyFeedListApiView(ListAPIView):
limit = serializer.validated_data.get("limit") limit = serializer.validated_data.get("limit")
offset = serializer.validated_data.get("offset") offset = serializer.validated_data.get("offset")
return self.request.user.posts.all()[offset: offset + limit] return self.request.user.posts.order_by("-createdAt").all()[
offset: offset + limit
]
class UserFeedListApiView(ListAPIView): class UserFeedListApiView(ListAPIView):
@@ -81,11 +83,11 @@ class UserFeedListApiView(ListAPIView):
limit = serializer.validated_data.get("limit") limit = serializer.validated_data.get("limit")
offset = serializer.validated_data.get("offset") offset = serializer.validated_data.get("offset")
return user.posts.all()[offset: offset + limit] return user.posts.order_by("-createdAt").all()[offset : offset + limit]
class LikePostApiView(APIView): class LikePostApiView(APIView):
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated, CanAccessPost]
def post(self, request, post_id): def post(self, request, post_id):
try: try:
@@ -103,7 +105,7 @@ class LikePostApiView(APIView):
class DislikePostApiView(APIView): class DislikePostApiView(APIView):
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated, CanAccessPost]
def post(self, request, post_id): def post(self, request, post_id):
try: try:
@@ -1,4 +1,4 @@
# Generated by Django 4.2.10 on 2024-03-03 15:01 # Generated by Django 4.2.10 on 2024-03-04 19:15
import api.users.validators import api.users.validators
import django.core.validators import django.core.validators
@@ -30,7 +30,7 @@ class Migration(migrations.Migration):
('password', models.CharField(max_length=100, validators=[django.core.validators.RegexValidator('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,100}$')])), ('password', models.CharField(max_length=100, validators=[django.core.validators.RegexValidator('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{6,100}$')])),
('countryCode', models.CharField(max_length=2, validators=[django.core.validators.RegexValidator('[a-zA-Z]{2}'), api.users.validators.CountryCodeValidator()])), ('countryCode', models.CharField(max_length=2, validators=[django.core.validators.RegexValidator('[a-zA-Z]{2}'), api.users.validators.CountryCodeValidator()])),
('isPublic', models.BooleanField()), ('isPublic', models.BooleanField()),
('phone', models.CharField(max_length=20, null=True, validators=[django.core.validators.MaxLengthValidator(20), django.core.validators.RegexValidator('\\+[\\d]+')])), ('phone', models.CharField(max_length=20, null=True, validators=[django.core.validators.MaxLengthValidator(20), django.core.validators.RegexValidator('^\\+\\d+')])),
('image', models.URLField(null=True)), ('image', models.URLField(null=True)),
('friends', models.ManyToManyField(blank=True, through='users.Friendship', to='users.profile')), ('friends', models.ManyToManyField(blank=True, through='users.Friendship', to='users.profile')),
], ],
+2 -3
View File
@@ -27,7 +27,7 @@ class Profile(models.Model):
isPublic = models.BooleanField() isPublic = models.BooleanField()
phone = models.CharField( phone = models.CharField(
max_length=20, max_length=20,
validators=[MaxLengthValidator(20), RegexValidator(r"\+[\d]+")], validators=[MaxLengthValidator(20), RegexValidator(r"^\+\d+")],
null=True, null=True,
) )
image = models.URLField(max_length=200, null=True) image = models.URLField(max_length=200, null=True)
@@ -56,7 +56,6 @@ class Profile(models.Model):
return self.liked_posts.add(post) return self.liked_posts.add(post)
def dislike_post(self, post): def dislike_post(self, post):
print(self, post)
self.liked_posts.remove(post) self.liked_posts.remove(post)
return self.disliked_posts.add(post) return self.disliked_posts.add(post)
@@ -82,7 +81,7 @@ class Profile(models.Model):
cls.objects.filter(phone=validated_data.get("phone")) cls.objects.filter(phone=validated_data.get("phone"))
.exclude(id=user_id) .exclude(id=user_id)
.exists() .exists()
): ) and validated_data.get("phone") is not None:
errors["phone"] = {"User with this phone already exists"} errors["phone"] = {"User with this phone already exists"}
return errors return errors
-2
View File
@@ -22,8 +22,6 @@ class UpdateProfileSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Profile model = Profile
fields = [ fields = [
"login",
"email",
"countryCode", "countryCode",
"isPublic", "isPublic",
"phone", "phone",
+4 -4
View File
@@ -116,7 +116,7 @@ class ProfileMeApiView(APIView):
) )
serializer.save() serializer.save()
return Response(serializer.data) return Response(self._get_profile_data(user))
raise ValidationError(serializer.errors) raise ValidationError(serializer.errors)
@@ -202,9 +202,9 @@ class FriendsListApiView(ListAPIView):
limit = serializer.validated_data.get("limit") limit = serializer.validated_data.get("limit")
offset = serializer.validated_data.get("offset") offset = serializer.validated_data.get("offset")
return Friendship.objects.filter(from_profile=self.request.user)[ return Friendship.objects.order_by("-addedAt").filter(
offset: offset + limit from_profile=self.request.user
] )[offset: offset + limit]
class PasswordChangeApiView(APIView): class PasswordChangeApiView(APIView):