From 392618ef8517309eac585907e0be374dd22f327a Mon Sep 17 00:00:00 2001 From: Armin Patel <72291325+arminpatel@users.noreply.github.com> Date: Thu, 7 Mar 2024 16:55:59 +0530 Subject: [PATCH] simplify products and add orders model (#134) * simplify product model * simplify products and add orders --- backend/core/settings/base.py | 1 + backend/core/urls.py | 2 ++ backend/orders/admin.py | 5 +++++ backend/orders/models.py | 14 ++++++++++++++ backend/orders/permissions.py | 5 +++++ backend/orders/serializers.py | 14 ++++++++++++++ backend/orders/urls.py | 8 ++++++++ backend/orders/views.py | 19 +++++++++++++++++++ backend/products/admin.py | 10 +++------- backend/products/models.py | 27 ++++++++------------------- backend/products/serializers.py | 33 +++++++++++++++++++++++++++++++++ backend/products/urls.py | 8 ++++++++ backend/products/views.py | 13 +++++++++++-- 13 files changed, 131 insertions(+), 28 deletions(-) create mode 100644 backend/orders/admin.py create mode 100644 backend/orders/models.py create mode 100644 backend/orders/permissions.py create mode 100644 backend/orders/serializers.py create mode 100644 backend/orders/urls.py create mode 100644 backend/orders/views.py create mode 100644 backend/products/serializers.py create mode 100644 backend/products/urls.py diff --git a/backend/core/settings/base.py b/backend/core/settings/base.py index 386e736..b817a45 100644 --- a/backend/core/settings/base.py +++ b/backend/core/settings/base.py @@ -47,6 +47,7 @@ 'products', 'events', 'tickets', + 'orders' ] REST_FRAMEWORK = { diff --git a/backend/core/urls.py b/backend/core/urls.py index 76d3807..fa8c8dd 100644 --- a/backend/core/urls.py +++ b/backend/core/urls.py @@ -24,6 +24,8 @@ path('api/token/', include('auth.urls')), path('api/accounts/', include('accounts.urls')), path('api/events/', include('events.urls')), + path('api/orders/', include('orders.urls')), + path('api/products/', include('products.urls')), path('api/tickets/', include('tickets.urls')), path('api/stripe/webhook/', stripe_webhook, name='stripe-webhook'), path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), diff --git a/backend/orders/admin.py b/backend/orders/admin.py new file mode 100644 index 0000000..6a151b8 --- /dev/null +++ b/backend/orders/admin.py @@ -0,0 +1,5 @@ +from django.contrib import admin + +from .models import Order + +admin.site.register(Order) diff --git a/backend/orders/models.py b/backend/orders/models.py new file mode 100644 index 0000000..61594ab --- /dev/null +++ b/backend/orders/models.py @@ -0,0 +1,14 @@ +from django.db import models +from products.models import Product +from accounts.models import Account + +class Order(models.Model): + product = models.ForeignKey(Product, on_delete=models.CASCADE) + quantity = models.IntegerField() + buyer = models.ForeignKey(Account, on_delete=models.PROTECT) + total = models.DecimalField(max_digits=10, decimal_places=2) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + def __str__(self): + return f"Order #{self.id} - {self.product.name}" diff --git a/backend/orders/permissions.py b/backend/orders/permissions.py new file mode 100644 index 0000000..d026ee3 --- /dev/null +++ b/backend/orders/permissions.py @@ -0,0 +1,5 @@ +from rest_framework.permissions import BasePermission + +class IsBuyerOrAdmin(BasePermission): + def has_object_permission(self, request, view, obj): + return obj.buyer == request.user or request.user.is_staff diff --git a/backend/orders/serializers.py b/backend/orders/serializers.py new file mode 100644 index 0000000..5709380 --- /dev/null +++ b/backend/orders/serializers.py @@ -0,0 +1,14 @@ +from rest_framework.serializers import ModelSerializer + +from .models import Order + +class OrderSerializer(ModelSerializer): + class Meta: + model = Order + fields = ('id', + 'product', + 'buyer', + 'quantity', + 'total', + 'created_at', + 'updated_at') diff --git a/backend/orders/urls.py b/backend/orders/urls.py new file mode 100644 index 0000000..5b61240 --- /dev/null +++ b/backend/orders/urls.py @@ -0,0 +1,8 @@ +from django.urls import path + +from . import views + +urlpatterns = [ + path('', views.ListCreateOrderView.as_view()), + path('/', views.RetrieveUpdateDestroyOrderView.as_view()), +] diff --git a/backend/orders/views.py b/backend/orders/views.py new file mode 100644 index 0000000..86950ff --- /dev/null +++ b/backend/orders/views.py @@ -0,0 +1,19 @@ +from rest_framework import generics +from rest_framework.permissions import IsAuthenticated + +from .models import Order +from .serializers import OrderSerializer +from .permissions import IsBuyerOrAdmin + +class ListCreateOrderView(generics.ListCreateAPIView): + serializer_class = OrderSerializer + permission_classes = (IsAuthenticated,) + + def get_queryset(self): + user = self.request.user + return Order.objects.filter(buyer=user) + +class RetrieveUpdateDestroyOrderView(generics.RetrieveUpdateDestroyAPIView): + queryset = Order.objects.all() + serializer_class = OrderSerializer + permission_classes = (IsBuyerOrAdmin,) diff --git a/backend/products/admin.py b/backend/products/admin.py index 4e7f4d7..431fc03 100644 --- a/backend/products/admin.py +++ b/backend/products/admin.py @@ -4,11 +4,8 @@ # Register your models here. class ProductAdmin(admin.ModelAdmin) : - list_display = ("name","description","category",'primary_variant',"created_at","updated_at") - fields = ("name","description","category","primary_variant",) - -class ProductVariationAdmin(admin.ModelAdmin) : - list_display = ("Product","ProductSize","ProductColor","price","quantity") + list_display = ("name","description","category",'color', 'size', 'price',"created_at","updated_at") + fields = ("name","description","category", "color", "size", "price") class ProductColorAdmin(admin.ModelAdmin) : list_display = ("color",) @@ -17,11 +14,10 @@ class ProductSizeAdmin(admin.ModelAdmin) : list_display = ("size",) class ProductImageAdmin(admin.ModelAdmin) : - list_display = ("product_variation_id","image") + list_display = ("product","image") admin.site.register(Product,ProductAdmin) -admin.site.register(ProductVariation,ProductVariationAdmin) admin.site.register(ProductColor,ProductColorAdmin) admin.site.register(ProductSize,ProductSizeAdmin) admin.site.register(ProductImage,ProductImageAdmin) diff --git a/backend/products/models.py b/backend/products/models.py index 5dfe54e..bc73b9f 100644 --- a/backend/products/models.py +++ b/backend/products/models.py @@ -1,7 +1,5 @@ from django.db import models -# Create your models here. - category_choices = [ ('clothing','Clothing'), ('rsvp','RSVP'), @@ -13,25 +11,19 @@ class Product(models.Model): blank=True) category = models.CharField(max_length=100, choices=category_choices) - primary_variant = models.OneToOneField( - 'ProductVariation', - on_delete=models.CASCADE, - default=None, - null=True, - blank=True,) - # Need to add Primary Variant and seller Id + color = models.CharField(max_length=100, blank = True) + size = models.CharField(max_length=100, blank = True) + price = models.IntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): - return self.name + return f'{self.name} {self.color} {self.size}' class ProductVariation(models.Model): - Product = models.ForeignKey(Product, - on_delete=models.CASCADE, - related_name='product_variations') + # Product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='product_variations') ProductColor = models.ForeignKey('ProductColor', on_delete=models.CASCADE) ProductSize = models.ForeignKey('ProductSize', @@ -62,12 +54,9 @@ def __str__(self): class ProductImage(models.Model): - product_variation_id = models.ForeignKey(ProductVariation, - on_delete=models.CASCADE, - related_name='product_images') + product = models.ForeignKey(Product, + on_delete=models.CASCADE, + related_name='product_images') image = models.ImageField(upload_to='product_images') required = ['image'] - - def __str__(self): - return f'{self.product_variation_id.Product.name} {self.product_variation_id.ProductColor.color} {self.product_variation_id.ProductSize.size}' diff --git a/backend/products/serializers.py b/backend/products/serializers.py new file mode 100644 index 0000000..1999a23 --- /dev/null +++ b/backend/products/serializers.py @@ -0,0 +1,33 @@ +from rest_framework.serializers import ModelSerializer + +from .models import Product, ProductImage + +class ProductImageSerializer(ModelSerializer): + class Meta: + model = ProductImage + fields = ( + 'id', + 'image', + ) + +class ProductSerializer(ModelSerializer): + product_images = ProductImageSerializer(many=True, read_only=True) + class Meta: + model = Product + fields = ( + 'id', + 'name', + 'description', + 'price', + 'color', + 'size', + 'created_at', + 'updated_at', + 'product_images', + ) + + def to_representation(self, instance): + representation = super().to_representation(instance) + filtered_images = instance.product_images.filter(product=instance) + representation['product_images'] = ProductImageSerializer(filtered_images, many=True).data + return representation diff --git a/backend/products/urls.py b/backend/products/urls.py new file mode 100644 index 0000000..a53a784 --- /dev/null +++ b/backend/products/urls.py @@ -0,0 +1,8 @@ +from django.urls import path + +from . import views + +urlpatterns = [ + path('', views.ListProductView.as_view()), + path('/', views.RetrieveProductView.as_view()), +] diff --git a/backend/products/views.py b/backend/products/views.py index 91ea44a..ba076ab 100644 --- a/backend/products/views.py +++ b/backend/products/views.py @@ -1,3 +1,12 @@ -from django.shortcuts import render +from rest_framework.generics import ListAPIView, RetrieveAPIView -# Create your views here. +from .models import Product +from .serializers import ProductSerializer + +class ListProductView(ListAPIView): + queryset = Product.objects.all() + serializer_class = ProductSerializer + +class RetrieveProductView(RetrieveAPIView): + queryset = Product.objects.all() + serializer_class = ProductSerializer