diff --git a/ecommerce/baskets/views.py b/ecommerce/baskets/views.py index ee32571..c4557b7 100644 --- a/ecommerce/baskets/views.py +++ b/ecommerce/baskets/views.py @@ -1,9 +1,16 @@ +from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned +from django.db.transaction import atomic from rest_framework import viewsets +from rest_framework import status +from rest_framework.decorators import action +from rest_framework.response import Response from baskets.filters import BasketItemFilter, BasketFilter from baskets.models import BasketItem, Basket -from baskets.serializers import BasketItemSerializer, BasketSerializer, BasketItemDetailedSerializer, BasketDetailedSerializer +from baskets.serializers import BasketItemSerializer, BasketSerializer, BasketItemDetailedSerializer, \ + BasketDetailedSerializer from core.mixins import DetailedViewSetMixin +from products.models import Product class BasketItemViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): @@ -15,6 +22,11 @@ class BasketItemViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): "detailed": BasketItemDetailedSerializer, } + def get_queryset(self): + queryset = super().get_queryset() + user = self.request.user + return queryset.filter(basket__customer__id=user) + class BasketViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): queryset = Basket.objects.all() @@ -24,3 +36,38 @@ class BasketViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): "detailed_list": BasketDetailedSerializer, "detailed": BasketDetailedSerializer, } + + def get_queryset(self): + queryset = super().get_queryset() + user = self.request.user + return queryset.filter(customer=user) + + @atomic() + @action(detail=True, methods=['post'], http_method_names=['post']) + def add_basket_item(self, request): + + user_id = self.request.user.id + product = Product.objects.get(id=request.data["product"]) + quantity = request.data["quantity"] + price = product.price + + try: + basket = Basket.objects.get(customer__id=user_id) + except ObjectDoesNotExist: + basket = Basket.objects.create(customer_id=user_id) + except MultipleObjectsReturned: + basket = Basket.objects.filter(customer__id=user_id).first() + + basket_item = BasketItem.objects.filter(basket=basket, product=product, price=price).first() + + if basket_item: + basket_item.quantity += quantity + + else: + basket_item = BasketItem.objects.create(basket=basket, product=product, quantity=quantity,price=price) + + basket_item.save() + basket.save() + + serializer = BasketItemSerializer(basket) + return Response(serializer.data, status=status.HTTP_201_CREATED) diff --git a/ecommerce/customers/serializers.py b/ecommerce/customers/serializers.py index ffad735..5cac39e 100644 --- a/ecommerce/customers/serializers.py +++ b/ecommerce/customers/serializers.py @@ -1,3 +1,5 @@ +from django.contrib.auth.password_validation import validate_password +from django.core.validators import EmailValidator from django.utils.translation import gettext_lazy as _ from django.db.transaction import atomic from rest_framework import serializers @@ -13,6 +15,31 @@ class Meta: fields = ("id", "first_name", "last_name", "email", "is_staff", "is_active", "date_joined") +class RegisterSerializer(serializers.ModelSerializer): + email = serializers.EmailField(required=True, validators=[EmailValidator()]) + password = serializers.CharField(required=True, validators=[validate_password]) + password_repeat = serializers.CharField(required=True) + + class Meta: + model = Customer + fields = fields = ("id", "first_name", "last_name", "email", "password", "password_repeat",) + + def validate(self, attrs): + if attrs["password"] != attrs["password_repeat"]: + raise ValidationError(_("Passwords should be the same")) + return attrs + + def create(self, validated_data): + customer = Customer.objects.create_user( + first_name=validated_data["first_name"], + last_name=validated_data["last_name"], + email=validated_data["email"], + password=validated_data["password"] + ) + customer.save() + return customer + + class ProfileSerializer(serializers.ModelSerializer): class Meta: diff --git a/ecommerce/customers/views.py b/ecommerce/customers/views.py index e2d05b6..7b00b09 100644 --- a/ecommerce/customers/views.py +++ b/ecommerce/customers/views.py @@ -1,5 +1,6 @@ from django.shortcuts import get_object_or_404 from rest_framework import viewsets, permissions, mixins +from rest_framework.permissions import AllowAny from rest_framework.viewsets import GenericViewSet from core.mixins import DetailedViewSetMixin @@ -8,7 +9,15 @@ from customers.models import Customer, Address, City, Country from customers.serializers import CustomerSerializer, AddressSerializer, CitySerializer, \ CountrySerializer, \ - AddressDetailedSerializer, CityDetailedSerializer, ProfileSerializer + AddressDetailedSerializer, CityDetailedSerializer,\ + ProfileSerializer, RegisterSerializer\ + + + +class RegisterViewSet(mixins.CreateModelMixin, GenericViewSet): + permission_classes = (AllowAny,) + queryset = Customer.objects.all() + serializer_class = RegisterSerializer class AdminCustomerViewSet(viewsets.ModelViewSet): diff --git a/ecommerce/ecommerce/urls.py b/ecommerce/ecommerce/urls.py index 28278ef..d985696 100644 --- a/ecommerce/ecommerce/urls.py +++ b/ecommerce/ecommerce/urls.py @@ -21,7 +21,7 @@ from baskets.views import BasketItemViewSet, BasketViewSet from core.views import APITokenObtainPairView from customers.views import AddressViewSet, CityViewSet, \ - CountryViewSet, AdminCustomerViewSet, MyProfileViewSet + CountryViewSet, AdminCustomerViewSet, MyProfileViewSet, RegisterViewSet from ecommerce.router import router from orders.views import OrderItemViewSet, OrderViewSet, BillingAddressViewSet, ShippingAddressViewSet, \ OrderBankAccountViewSet @@ -46,7 +46,7 @@ router.register("banks", BankViewSet) router.register("admin-products", AdminProductViewSet, basename="admin-product") router.register("admin-customers", AdminCustomerViewSet, basename="admin-customer") - +router.register("register", RegisterViewSet) urlpatterns = [ path("api/", include(router.urls)), diff --git a/ecommerce/orders/views.py b/ecommerce/orders/views.py index dde7137..f6faa3e 100644 --- a/ecommerce/orders/views.py +++ b/ecommerce/orders/views.py @@ -1,4 +1,4 @@ -from rest_framework import viewsets +from rest_framework import viewsets, permissions from core.mixins import DetailedViewSetMixin from orders.filters import OrderItemFilter, OrderFilter, BillingAddressFilter, ShippingAddressFilter, \ @@ -10,6 +10,7 @@ class OrderItemViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): + permission_classes = (permissions.IsAuthenticated,) queryset = OrderItem.objects.all() serializer_class = OrderItemSerializer filterset_class = OrderItemFilter @@ -20,6 +21,7 @@ class OrderItemViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): class OrderViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): + permission_classes = (permissions.IsAuthenticated,) queryset = Order.objects.all() serializer_class = OrderSerializer filterset_class = OrderFilter @@ -30,6 +32,7 @@ class OrderViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): class BillingAddressViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): + permission_classes = (permissions.IsAuthenticated,) queryset = BillingAddress.objects.all() serializer_class = BillingAddressSerializer filterset_class = BillingAddressFilter @@ -40,6 +43,7 @@ class BillingAddressViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): class ShippingAddressViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): + permission_classes = (permissions.IsAuthenticated,) queryset = ShippingAddress.objects.all() serializer_class = ShippingAddressSerializer filterset_class = ShippingAddressFilter @@ -50,6 +54,7 @@ class ShippingAddressViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): class OrderBankAccountViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): + permission_classes = (permissions.IsAuthenticated,) queryset = OrderBankAccount.objects.all() serializer_class = OrderBankAccountSerializer filterset_class = OrderBankAccountFilter diff --git a/ecommerce/payments/views.py b/ecommerce/payments/views.py index 09b28a7..6055b89 100644 --- a/ecommerce/payments/views.py +++ b/ecommerce/payments/views.py @@ -1,4 +1,4 @@ -from rest_framework import viewsets +from rest_framework import viewsets, permissions from core.mixins import DetailedViewSetMixin from payments.filters import BankAccountFilter, BankFilter @@ -7,6 +7,7 @@ class BankAccountViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): + permission_classes = (permissions.IsAuthenticated,) queryset = BankAccount.objects.all() serializer_class = BankAccountSerializer filterset_class = BankAccountFilter @@ -17,6 +18,7 @@ class BankAccountViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): class BankViewSet(viewsets.ModelViewSet): + permission_classes = (permissions.IsAuthenticated,) queryset = Bank.objects.all() serializer_class = BankSerializer filterset_class = BankFilter diff --git a/ecommerce/products/views.py b/ecommerce/products/views.py index 4f75c73..f31e1ca 100644 --- a/ecommerce/products/views.py +++ b/ecommerce/products/views.py @@ -37,12 +37,14 @@ class AdminProductViewSet(DetailedViewSetMixin, viewsets.ModelViewSet): class CategoryViewSet(viewsets.ModelViewSet): + permission_classes = () http_method_names = ["get"] queryset = Category.objects.all() serializer_class = CategorySerializer class PriceViewSet(viewsets.ModelViewSet): + permission_classes = () http_method_names = ["get"] queryset = Price.objects.all() filterset_class = PriceFilter