Forráskód Böngészése

added api to fetch all attr/edit/add etc

Harshit Pathak 3 hónapja
szülő
commit
8034a04abb
2 módosított fájl, 220 hozzáadás és 1 törlés
  1. 2 1
      attr_extraction/urls.py
  2. 218 0
      attr_extraction/views.py

+ 2 - 1
attr_extraction/urls.py

@@ -1,6 +1,6 @@
 # ==================== urls.py ====================
 from django.urls import path
-from .views import ExtractProductAttributesView, ProductAttributesUploadView, BatchExtractProductAttributesView, ProductListView, ProductUploadExcelView
+from .views import ExtractProductAttributesView, ProductTypeAttributesView, ProductAttributesUploadView, BatchExtractProductAttributesView, ProductListView, ProductUploadExcelView
 
 urlpatterns = [
     path('extract/', ExtractProductAttributesView.as_view(), name='extract-attributes'),
@@ -8,5 +8,6 @@ urlpatterns = [
     path('products/', ProductListView.as_view(), name='batch-extract-attributes'),
     path('products/upload-excel/', ProductUploadExcelView.as_view(), name='product-upload-excel'),
     path('products/upload-attributes/', ProductAttributesUploadView.as_view(), name='product-upload-excel'),
+    path('products/attributes/', ProductTypeAttributesView.as_view(), name='product-upload-excel'),
 
 ]

+ 218 - 0
attr_extraction/views.py

@@ -694,3 +694,221 @@ class ProductAttributesUploadView(APIView):
 
         except Exception as e:
             return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+
+
+
+
+from rest_framework.views import APIView
+from rest_framework.response import Response
+from rest_framework import status
+from .models import ProductType, ProductAttribute, AttributePossibleValue
+from .serializers import ProductTypeSerializer, ProductAttributeSerializer, AttributePossibleValueSerializer
+from django.db import transaction
+
+class ProductTypeAttributesView(APIView):
+    """
+    API to view, create, update, and delete product type attributes and their possible values.
+    Also supports dynamic product type creation.
+    """
+
+    def get(self, request):
+        """
+        Retrieve all product types with their attributes and possible values.
+        """
+        product_types = ProductType.objects.all()
+        serializer = ProductTypeSerializer(product_types, many=True)
+        
+        # Transform the serialized data into the requested format
+        result = []
+        for pt in serializer.data:
+            for attr in pt['attributes']:
+                result.append({
+                    'product_type': pt['name'],
+                    'attribute_name': attr['name'],
+                    'is_mandatory': 'Yes' if attr['is_mandatory'] else 'No',
+                    'possible_values': ', '.join([pv['value'] for pv in attr['possible_values']])
+                })
+                
+        return Response(result, status=status.HTTP_200_OK)
+
+    def post(self, request):
+        """
+        Create a new product type or attribute with possible values.
+        Expected payload example:
+        {
+            "product_type": "Hardware Screws",
+            "attribute_name": "Material",  // Optional if only creating product type
+            "is_mandatory": "Yes",        // Optional if only creating product type
+            "possible_values": "Steel, Zinc Plated, Stainless Steel"  // Optional
+        }
+        """
+        try:
+            product_type_name = request.data.get('product_type')
+            attribute_name = request.data.get('attribute_name', '')
+            is_mandatory = request.data.get('is_mandatory', '').lower() in ['yes', 'true', '1']
+            possible_values = request.data.get('possible_values', '')
+
+            if not product_type_name:
+                return Response({
+                    "error": "product_type is required"
+                }, status=status.HTTP_400_BAD_REQUEST)
+
+            with transaction.atomic():
+                # Get or create product type
+                product_type, created = ProductType.objects.get_or_create(name=product_type_name)
+
+                if created and not attribute_name:
+                    # Only product type was created
+                    return Response({
+                        "message": f"Product type '{product_type_name}' created successfully",
+                        "data": {"product_type": product_type_name}
+                    }, status=status.HTTP_201_CREATED)
+
+                if attribute_name:
+                    # Create attribute
+                    attribute, attr_created = ProductAttribute.objects.get_or_create(
+                        product_type=product_type,
+                        name=attribute_name,
+                        defaults={'is_mandatory': is_mandatory}
+                    )
+                    
+                    if not attr_created:
+                        return Response({
+                            "error": f"Attribute '{attribute_name}' already exists for product type '{product_type_name}'"
+                        }, status=status.HTTP_400_BAD_REQUEST)
+
+                    # Handle possible values
+                    if possible_values:
+                        for val in [v.strip() for v in possible_values.split(',') if v.strip()]:
+                            AttributePossibleValue.objects.create(attribute=attribute, value=val)
+
+                    return Response({
+                        "message": "Attribute created successfully",
+                        "data": {
+                            "product_type": product_type_name,
+                            "attribute_name": attribute_name,
+                            "is_mandatory": "Yes" if is_mandatory else "No",
+                            "possible_values": possible_values
+                        }
+                    }, status=status.HTTP_201_CREATED)
+
+                return Response({
+                    "message": f"Product type '{product_type_name}' already exists",
+                    "data": {"product_type": product_type_name}
+                }, status=status.HTTP_200_OK)
+
+        except Exception as e:
+            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+    def put(self, request):
+        """
+        Update an existing product type attribute and its possible values.
+        Expected payload example:
+        {
+            "product_type": "Hardware Screws",
+            "attribute_name": "Material",
+            "is_mandatory": "Yes",
+            "possible_values": "Steel, Zinc Plated, Stainless Steel, Brass"
+        }
+        """
+        try:
+            product_type_name = request.data.get('product_type')
+            attribute_name = request.data.get('attribute_name')
+            is_mandatory = request.data.get('is_mandatory', '').lower() in ['yes', 'true', '1']
+            possible_values = request.data.get('possible_values', '')
+
+            if not all([product_type_name, attribute_name]):
+                return Response({
+                    "error": "product_type and attribute_name are required"
+                }, status=status.HTTP_400_BAD_REQUEST)
+
+            with transaction.atomic():
+                try:
+                    product_type = ProductType.objects.get(name=product_type_name)
+                    attribute = ProductAttribute.objects.get(
+                        product_type=product_type,
+                        name=attribute_name
+                    )
+                except ProductType.DoesNotExist:
+                    return Response({
+                        "error": f"Product type '{product_type_name}' not found"
+                    }, status=status.HTTP_404_NOT_FOUND)
+                except ProductAttribute.DoesNotExist:
+                    return Response({
+                        "error": f"Attribute '{attribute_name}' not found for product type '{product_type_name}'"
+                    }, status=status.HTTP_404_NOT_FOUND)
+
+                # Update attribute
+                attribute.is_mandatory = is_mandatory
+                attribute.save()
+
+                # Update possible values
+                AttributePossibleValue.objects.filter(attribute=attribute).delete()
+                if possible_values:
+                    for val in [v.strip() for v in possible_values.split(',') if v.strip()]:
+                        AttributePossibleValue.objects.create(attribute=attribute, value=val)
+
+                return Response({
+                    "message": "Attribute updated successfully",
+                    "data": {
+                        "product_type": product_type_name,
+                        "attribute_name": attribute_name,
+                        "is_mandatory": "Yes" if is_mandatory else "No",
+                        "possible_values": possible_values
+                    }
+                }, status=status.HTTP_200_OK)
+
+        except Exception as e:
+            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+    def delete(self, request):
+        """
+        Delete a product type or a specific attribute.
+        Expected payload example:
+        {
+            "product_type": "Hardware Screws",
+            "attribute_name": "Material"  // Optional: if omitted, deletes entire product type
+        }
+        """
+        try:
+            product_type_name = request.data.get('product_type')
+            attribute_name = request.data.get('attribute_name', '')
+
+            if not product_type_name:
+                return Response({
+                    "error": "product_type is required"
+                }, status=status.HTTP_400_BAD_REQUEST)
+
+            with transaction.atomic():
+                try:
+                    product_type = ProductType.objects.get(name=product_type_name)
+                except ProductType.DoesNotExist:
+                    return Response({
+                        "error": f"Product type '{product_type_name}' not found"
+                    }, status=status.HTTP_404_NOT_FOUND)
+
+                if attribute_name:
+                    # Delete specific attribute
+                    try:
+                        attribute = ProductAttribute.objects.get(
+                            product_type=product_type,
+                            name=attribute_name
+                        )
+                        attribute.delete()
+                        return Response({
+                            "message": f"Attribute '{attribute_name}' deleted successfully from product type '{product_type_name}'"
+                        }, status=status.HTTP_200_OK)
+                    except ProductAttribute.DoesNotExist:
+                        return Response({
+                            "error": f"Attribute '{attribute_name}' not found for product type '{product_type_name}'"
+                        }, status=status.HTTP_404_NOT_FOUND)
+                else:
+                    # Delete entire product type (and its attributes and possible values)
+                    product_type.delete()
+                    return Response({
+                        "message": f"Product type '{product_type_name}' and all its attributes deleted successfully"
+                    }, status=status.HTTP_200_OK)
+
+        except Exception as e:
+            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)