From 6401ce2a24298cac7612065abe0ea6b83cbbba81 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Tue, 14 Jan 2025 22:43:34 +0330 Subject: [PATCH 1/6] add category search --- backend/product/views.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/backend/product/views.py b/backend/product/views.py index 6cd40d4..563e442 100644 --- a/backend/product/views.py +++ b/backend/product/views.py @@ -8,8 +8,7 @@ from django.db.models import Q from django.shortcuts import get_object_or_404 from rest_framework.permissions import IsAuthenticatedOrReadOnly from utils.pagination import StructurePagination -from drf_spectacular.utils import extend_schema, OpenApiParameter -from drf_spectacular.types import OpenApiTypes +from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes from rest_framework.permissions import AllowAny @@ -26,8 +25,26 @@ from rest_framework.permissions import AllowAny class AllCategories(APIView): serializer_class = CategorySerializer authentication_classes = [] + @extend_schema( + parameters=[ + OpenApiParameter( + name="search", + description="Search by category name or description.", + required=False, + type=OpenApiTypes.STR, + ) + ], + responses={ + 200: CategorySerializer(many=True), + 404: OpenApiTypes.OBJECT, + }, + ) def get(self, request): - categories = CategoryModel.objects.all() + search_query = request.query_params.get('search', None) + if search_query: + categories = CategoryModel.objects.filter(Q(name__icontains=search_query) | Q(slug__icontains=search_query)) + else: + categories = CategoryModel.objects.all() categories_ser = self.serializer_class(instance=categories, many=True) return Response({"categories": categories_ser.data}, status=status.HTTP_200_OK) @@ -40,11 +57,6 @@ class ProductView(APIView): product_ser = self.serializer_class(instance=product, many=False) return Response(product_ser.data, status=status.HTTP_200_OK) -from rest_framework.response import Response -from rest_framework.views import APIView -from rest_framework import status -from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes -from django.db.models import Q class AllProductsView(APIView): serializer_class = ProductSerializer From 830e20dec35072220614ef4dfc618308e94d94ed Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Tue, 14 Jan 2025 22:50:43 +0330 Subject: [PATCH 2/6] price formating --- backend/product/serializers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/product/serializers.py b/backend/product/serializers.py index a4726f9..935da30 100644 --- a/backend/product/serializers.py +++ b/backend/product/serializers.py @@ -13,12 +13,12 @@ class ProductChatSerializer(serializers.ModelSerializer): if dollor_price is None: raise ValidationError({"dollor_price": "The 'dollor_price' must be provided in the context for dollar pricing."}) if obj.currency == 'toman': - return obj.price + toman_price = obj.price elif obj.currency == 'dollor': - return obj.price * dollor_price + toman_price = obj.price * dollor_price elif obj.currency == 'derham': - return obj.price * dollor_price * dollar_to_dirham - + toman_price = obj.price * dollor_price * dollar_to_dirham + return "{:,.0f} تومان".format(toman_price) class ProductSerializer(ProductChatSerializer): class Meta: model = ProductModel From abceb2a06617b74ffab9d8920d62f5d92a2f9a29 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Tue, 14 Jan 2025 23:24:29 +0330 Subject: [PATCH 3/6] add is_new field --- backend/product/serializers.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/backend/product/serializers.py b/backend/product/serializers.py index 935da30..277e28b 100644 --- a/backend/product/serializers.py +++ b/backend/product/serializers.py @@ -1,8 +1,11 @@ from .models import * from rest_framework import serializers +from django.utils import timezone +from datetime import timedelta class ProductChatSerializer(serializers.ModelSerializer): price = serializers.SerializerMethodField() + is_new = serializers.SerializerMethodField() class Meta: model = ProductModel fields = ['name', 'description', 'price', 'in_stock', 'discount', ] @@ -19,6 +22,9 @@ class ProductChatSerializer(serializers.ModelSerializer): elif obj.currency == 'derham': toman_price = obj.price * dollor_price * dollar_to_dirham return "{:,.0f} تومان".format(toman_price) + def get_is_new(self, obj): + return timezone.now() < obj.created_at + timedelta(days=7) + class ProductSerializer(ProductChatSerializer): class Meta: model = ProductModel From 360d71af8d656f81c897a3775216ead1542ab1fe Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Tue, 14 Jan 2025 23:57:53 +0330 Subject: [PATCH 4/6] 7 days for refresh token and 1 day for token and verify token --- backend/account/urls.py | 1 + backend/core/settings.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/account/urls.py b/backend/account/urls.py index c01ce3a..93ac5cb 100644 --- a/backend/account/urls.py +++ b/backend/account/urls.py @@ -4,6 +4,7 @@ from djoser.urls.jwt import views as djoser_jwt_views urlpatterns = [ path('profile', views.ProfileView.as_view()), + path('verify', djoser_jwt_views.TokenVerifyView.as_view(), name='jwt-verify'), path('send_otp', views.SendOTPView.as_view(), name='send-otp-view'), path('address/create', views.CreateAddressView.as_view(), name='create-address'), path('address/edit/', views.EditAddressView.as_view(), name='edit-address'), diff --git a/backend/core/settings.py b/backend/core/settings.py index 05712e2..dcee877 100644 --- a/backend/core/settings.py +++ b/backend/core/settings.py @@ -201,7 +201,7 @@ REST_FRAMEWORK = { SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=1), - 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), + 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), 'ROTATE_REFRESH_TOKENS': True, 'BLACKLIST_AFTER_ROTATION': True, } From 5dfe35e42d87e817766e4feb30726ff4b3a2c563 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Wed, 15 Jan 2025 00:20:35 +0330 Subject: [PATCH 5/6] 2 min token --- backend/core/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/core/settings.py b/backend/core/settings.py index dcee877..6336fd9 100644 --- a/backend/core/settings.py +++ b/backend/core/settings.py @@ -200,7 +200,7 @@ REST_FRAMEWORK = { } SIMPLE_JWT = { - 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=1), + 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=2), 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), 'ROTATE_REFRESH_TOKENS': True, 'BLACKLIST_AFTER_ROTATION': True, From f178754ba61183610885e20f72c4b8e43ddc3222 Mon Sep 17 00:00:00 2001 From: Parsa Nazer Date: Wed, 15 Jan 2025 01:26:06 +0330 Subject: [PATCH 6/6] add refresh token --- backend/core/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/core/urls.py b/backend/core/urls.py index d8e4a3e..2286b6f 100644 --- a/backend/core/urls.py +++ b/backend/core/urls.py @@ -16,7 +16,7 @@ urlpatterns = [ path('token/', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'), - # path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), + path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('admin/', admin.site.urls), path('schema/', SpectacularAPIView.as_view(), name='schema'), # path('comment/', views.CommentView.as_view(), name='comment-list'),