|
@@ -364,9 +364,65 @@ from .models import Product
|
|
|
from .serializers import ProductSerializer
|
|
from .serializers import ProductSerializer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+# class ProductUploadExcelView(APIView):
|
|
|
|
|
+# """
|
|
|
|
|
+# POST API to upload an Excel file and add data to Product model
|
|
|
|
|
+# """
|
|
|
|
|
+# parser_classes = (MultiPartParser, FormParser)
|
|
|
|
|
+
|
|
|
|
|
+# def post(self, request, *args, **kwargs):
|
|
|
|
|
+# file_obj = request.FILES.get('file')
|
|
|
|
|
+# if not file_obj:
|
|
|
|
|
+# return Response({'error': 'No file provided'}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
|
+
|
|
|
|
|
+# try:
|
|
|
|
|
+# # Read the Excel file
|
|
|
|
|
+# df = pd.read_excel(file_obj)
|
|
|
|
|
+
|
|
|
|
|
+# # Normalize column names
|
|
|
|
|
+# df.columns = [c.strip().lower().replace(' ', '_') for c in df.columns]
|
|
|
|
|
+
|
|
|
|
|
+# # Expected columns
|
|
|
|
|
+# expected_cols = {
|
|
|
|
|
+# 'item_id',
|
|
|
|
|
+# 'product_name',
|
|
|
|
|
+# 'product_long_description',
|
|
|
|
|
+# 'product_short_description',
|
|
|
|
|
+# 'product_type',
|
|
|
|
|
+# 'image_path'
|
|
|
|
|
+# }
|
|
|
|
|
+
|
|
|
|
|
+# if not expected_cols.issubset(df.columns):
|
|
|
|
|
+# return Response({
|
|
|
|
|
+# 'error': 'Missing required columns',
|
|
|
|
|
+# 'required_columns': list(expected_cols)
|
|
|
|
|
+# }, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
|
+
|
|
|
|
|
+# # Loop through rows and create Product entries
|
|
|
|
|
+# created_count = 0
|
|
|
|
|
+# for _, row in df.iterrows():
|
|
|
|
|
+# Product.objects.create(
|
|
|
|
|
+# item_id=row.get('item_id', ''),
|
|
|
|
|
+# product_name=row.get('product_name', ''),
|
|
|
|
|
+# product_long_description=row.get('product_long_description', ''),
|
|
|
|
|
+# product_short_description=row.get('product_short_description', ''),
|
|
|
|
|
+# product_type=row.get('product_type', ''),
|
|
|
|
|
+# image_path=row.get('image_path', ''),
|
|
|
|
|
+# )
|
|
|
|
|
+# created_count += 1
|
|
|
|
|
+
|
|
|
|
|
+# return Response({
|
|
|
|
|
+# 'message': f'Successfully uploaded {created_count} products.'
|
|
|
|
|
+# }, status=status.HTTP_201_CREATED)
|
|
|
|
|
+
|
|
|
|
|
+# except Exception as e:
|
|
|
|
|
+# return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
class ProductUploadExcelView(APIView):
|
|
class ProductUploadExcelView(APIView):
|
|
|
"""
|
|
"""
|
|
|
- POST API to upload an Excel file and add data to Product model
|
|
|
|
|
|
|
+ POST API to upload an Excel file and add data to Product model (skip duplicates)
|
|
|
"""
|
|
"""
|
|
|
parser_classes = (MultiPartParser, FormParser)
|
|
parser_classes = (MultiPartParser, FormParser)
|
|
|
|
|
|
|
@@ -376,13 +432,10 @@ class ProductUploadExcelView(APIView):
|
|
|
return Response({'error': 'No file provided'}, status=status.HTTP_400_BAD_REQUEST)
|
|
return Response({'error': 'No file provided'}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
|
|
|
|
try:
|
|
try:
|
|
|
- # Read the Excel file
|
|
|
|
|
|
|
+ import pandas as pd
|
|
|
df = pd.read_excel(file_obj)
|
|
df = pd.read_excel(file_obj)
|
|
|
-
|
|
|
|
|
- # Normalize column names
|
|
|
|
|
df.columns = [c.strip().lower().replace(' ', '_') for c in df.columns]
|
|
df.columns = [c.strip().lower().replace(' ', '_') for c in df.columns]
|
|
|
|
|
|
|
|
- # Expected columns
|
|
|
|
|
expected_cols = {
|
|
expected_cols = {
|
|
|
'item_id',
|
|
'item_id',
|
|
|
'product_name',
|
|
'product_name',
|
|
@@ -398,11 +451,19 @@ class ProductUploadExcelView(APIView):
|
|
|
'required_columns': list(expected_cols)
|
|
'required_columns': list(expected_cols)
|
|
|
}, status=status.HTTP_400_BAD_REQUEST)
|
|
}, status=status.HTTP_400_BAD_REQUEST)
|
|
|
|
|
|
|
|
- # Loop through rows and create Product entries
|
|
|
|
|
created_count = 0
|
|
created_count = 0
|
|
|
|
|
+ skipped_count = 0
|
|
|
|
|
+
|
|
|
for _, row in df.iterrows():
|
|
for _, row in df.iterrows():
|
|
|
|
|
+ item_id = row.get('item_id', '')
|
|
|
|
|
+
|
|
|
|
|
+ # Check if this item already exists
|
|
|
|
|
+ if Product.objects.filter(item_id=item_id).exists():
|
|
|
|
|
+ skipped_count += 1
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
Product.objects.create(
|
|
Product.objects.create(
|
|
|
- item_id=row.get('item_id', ''),
|
|
|
|
|
|
|
+ item_id=item_id,
|
|
|
product_name=row.get('product_name', ''),
|
|
product_name=row.get('product_name', ''),
|
|
|
product_long_description=row.get('product_long_description', ''),
|
|
product_long_description=row.get('product_long_description', ''),
|
|
|
product_short_description=row.get('product_short_description', ''),
|
|
product_short_description=row.get('product_short_description', ''),
|
|
@@ -412,7 +473,8 @@ class ProductUploadExcelView(APIView):
|
|
|
created_count += 1
|
|
created_count += 1
|
|
|
|
|
|
|
|
return Response({
|
|
return Response({
|
|
|
- 'message': f'Successfully uploaded {created_count} products.'
|
|
|
|
|
|
|
+ 'message': f'Successfully uploaded {created_count} products.',
|
|
|
|
|
+ 'skipped': f'Skipped {skipped_count} duplicates.'
|
|
|
}, status=status.HTTP_201_CREATED)
|
|
}, status=status.HTTP_201_CREATED)
|
|
|
|
|
|
|
|
except Exception as e:
|
|
except Exception as e:
|