|
|
@@ -1,3 +1,9 @@
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+# # ==================== serializers.py ====================
|
|
|
# from rest_framework import serializers
|
|
|
|
|
|
# class ProductInputSerializer(serializers.Serializer):
|
|
|
@@ -6,19 +12,36 @@
|
|
|
# title = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
# short_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
# long_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
+# image_url = serializers.URLField(required=False, allow_blank=True, allow_null=True)
|
|
|
+
|
|
|
+# class MandatoryAttrsField(serializers.DictField):
|
|
|
+# """Custom DictField to validate mandatory_attrs structure."""
|
|
|
+# child = serializers.ListField(child=serializers.CharField())
|
|
|
+
|
|
|
+# class ProductBatchInputSerializer(serializers.Serializer):
|
|
|
+# """Serializer for an individual product input within the batch request."""
|
|
|
+# item_id = serializers.CharField(required=True)
|
|
|
+# mandatory_attrs = MandatoryAttrsField(
|
|
|
+# required=True,
|
|
|
+# help_text="A dictionary of attribute names and their possible values."
|
|
|
+# )
|
|
|
+# # You can also allow per-product model/flags if needed, but keeping it batch-level for simplicity here.
|
|
|
|
|
|
|
|
|
# class SingleProductRequestSerializer(serializers.Serializer):
|
|
|
# """Serializer for single product extraction request."""
|
|
|
-# title = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
-# short_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
-# long_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
+# # title = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
+# # short_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
+# # long_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
+# # image_url = serializers.URLField(required=False, allow_blank=True, allow_null=True)
|
|
|
+# item_id = serializers.CharField(required=True)
|
|
|
# mandatory_attrs = serializers.DictField(
|
|
|
# child=serializers.ListField(child=serializers.CharField()),
|
|
|
# required=True
|
|
|
# )
|
|
|
# model = serializers.CharField(required=False, default="llama-3.1-8b-instant")
|
|
|
# extract_additional = serializers.BooleanField(required=False, default=True)
|
|
|
+# process_image = serializers.BooleanField(required=False, default=True)
|
|
|
|
|
|
# def validate_model(self, value):
|
|
|
# from django.conf import settings
|
|
|
@@ -29,20 +52,19 @@
|
|
|
# return value
|
|
|
|
|
|
|
|
|
+
|
|
|
# class BatchProductRequestSerializer(serializers.Serializer):
|
|
|
-# """Serializer for batch product extraction request."""
|
|
|
+# """Serializer for batch product extraction request (with item-specific attributes)."""
|
|
|
# products = serializers.ListField(
|
|
|
-# child=ProductInputSerializer(),
|
|
|
+# child=ProductBatchInputSerializer(), # <--- Changed
|
|
|
# required=True,
|
|
|
# min_length=1
|
|
|
# )
|
|
|
-# mandatory_attrs = serializers.DictField(
|
|
|
-# child=serializers.ListField(child=serializers.CharField()),
|
|
|
-# required=True
|
|
|
-# )
|
|
|
# model = serializers.CharField(required=False, default="llama-3.1-8b-instant")
|
|
|
# extract_additional = serializers.BooleanField(required=False, default=True)
|
|
|
-
|
|
|
+# process_image = serializers.BooleanField(required=False, default=True)
|
|
|
+
|
|
|
+# # ... validate_model method ...
|
|
|
# def validate_model(self, value):
|
|
|
# from django.conf import settings
|
|
|
# if value not in settings.SUPPORTED_MODELS:
|
|
|
@@ -50,7 +72,8 @@
|
|
|
# f"Model must be one of {settings.SUPPORTED_MODELS}"
|
|
|
# )
|
|
|
# return value
|
|
|
-
|
|
|
+
|
|
|
+# # ... validate_products method (updated to use products instead of item_ids) ...
|
|
|
# def validate_products(self, value):
|
|
|
# from django.conf import settings
|
|
|
# max_size = getattr(settings, 'MAX_BATCH_SIZE', 100)
|
|
|
@@ -60,12 +83,18 @@
|
|
|
# )
|
|
|
# return value
|
|
|
|
|
|
+# class OCRResultSerializer(serializers.Serializer):
|
|
|
+# """Serializer for OCR results."""
|
|
|
+# detected_text = serializers.ListField(child=serializers.DictField())
|
|
|
+# extracted_attributes = serializers.DictField()
|
|
|
+
|
|
|
|
|
|
# class ProductAttributeResultSerializer(serializers.Serializer):
|
|
|
# """Serializer for individual product extraction result."""
|
|
|
# product_id = serializers.CharField(required=False)
|
|
|
# mandatory = serializers.DictField()
|
|
|
# additional = serializers.DictField(required=False)
|
|
|
+# ocr_results = OCRResultSerializer(required=False)
|
|
|
# error = serializers.CharField(required=False)
|
|
|
# raw_output = serializers.CharField(required=False)
|
|
|
|
|
|
@@ -76,6 +105,101 @@
|
|
|
# total_products = serializers.IntegerField()
|
|
|
# successful = serializers.IntegerField()
|
|
|
# failed = serializers.IntegerField()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+# from rest_framework import serializers
|
|
|
+# from .models import Product
|
|
|
+
|
|
|
+# class ProductSerializer(serializers.ModelSerializer):
|
|
|
+# product_type_details = serializers.SerializerMethodField()
|
|
|
+
|
|
|
+# class Meta:
|
|
|
+# model = Product
|
|
|
+# fields = [
|
|
|
+# 'id',
|
|
|
+# 'item_id',
|
|
|
+# 'product_name',
|
|
|
+# 'product_long_description',
|
|
|
+# 'product_short_description',
|
|
|
+# 'product_type',
|
|
|
+# 'image_path',
|
|
|
+# 'image',
|
|
|
+# 'product_type_details', # new field
|
|
|
+# ]
|
|
|
+
|
|
|
+# def get_product_type_details(self, obj):
|
|
|
+# # Fetch ProductType object for this product
|
|
|
+# try:
|
|
|
+# product_type = ProductType.objects.get(name=obj.product_type)
|
|
|
+# except ProductType.DoesNotExist:
|
|
|
+# return []
|
|
|
+
|
|
|
+# # Serialize its attributes
|
|
|
+# attributes = ProductAttribute.objects.filter(product_type=product_type)
|
|
|
+# return [
|
|
|
+# {
|
|
|
+# "attribute_name": attr.name,
|
|
|
+# "is_mandatory": "Yes" if attr.is_mandatory else "No",
|
|
|
+# "possible_values": [pv.value for pv in attr.possible_values.all()]
|
|
|
+# }
|
|
|
+# for attr in attributes
|
|
|
+# ]
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+# from rest_framework import serializers
|
|
|
+# from .models import Product, ProductType, ProductAttribute, AttributePossibleValue
|
|
|
+
|
|
|
+# class AttributePossibleValueSerializer(serializers.ModelSerializer):
|
|
|
+# class Meta:
|
|
|
+# model = AttributePossibleValue
|
|
|
+# fields = ['value']
|
|
|
+
|
|
|
+# class ProductAttributeSerializer(serializers.ModelSerializer):
|
|
|
+# possible_values = AttributePossibleValueSerializer(many=True, read_only=True)
|
|
|
+
|
|
|
+# class Meta:
|
|
|
+# model = ProductAttribute
|
|
|
+# fields = ['name', 'is_mandatory', 'possible_values']
|
|
|
+
|
|
|
+# class ProductTypeSerializer(serializers.ModelSerializer):
|
|
|
+# attributes = ProductAttributeSerializer(many=True, read_only=True)
|
|
|
+
|
|
|
+# class Meta:
|
|
|
+# model = ProductType
|
|
|
+# fields = ['name', 'attributes']
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
@@ -86,6 +210,8 @@
|
|
|
|
|
|
# ==================== serializers.py ====================
|
|
|
from rest_framework import serializers
|
|
|
+from .models import Product, ProductType, ProductAttribute, AttributePossibleValue
|
|
|
+
|
|
|
|
|
|
class ProductInputSerializer(serializers.Serializer):
|
|
|
"""Serializer for individual product input."""
|
|
|
@@ -95,10 +221,12 @@ class ProductInputSerializer(serializers.Serializer):
|
|
|
long_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
image_url = serializers.URLField(required=False, allow_blank=True, allow_null=True)
|
|
|
|
|
|
+
|
|
|
class MandatoryAttrsField(serializers.DictField):
|
|
|
"""Custom DictField to validate mandatory_attrs structure."""
|
|
|
child = serializers.ListField(child=serializers.CharField())
|
|
|
|
|
|
+
|
|
|
class ProductBatchInputSerializer(serializers.Serializer):
|
|
|
"""Serializer for an individual product input within the batch request."""
|
|
|
item_id = serializers.CharField(required=True)
|
|
|
@@ -106,15 +234,10 @@ class ProductBatchInputSerializer(serializers.Serializer):
|
|
|
required=True,
|
|
|
help_text="A dictionary of attribute names and their possible values."
|
|
|
)
|
|
|
- # You can also allow per-product model/flags if needed, but keeping it batch-level for simplicity here.
|
|
|
|
|
|
|
|
|
class SingleProductRequestSerializer(serializers.Serializer):
|
|
|
"""Serializer for single product extraction request."""
|
|
|
- # title = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
- # short_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
- # long_desc = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
|
|
- # image_url = serializers.URLField(required=False, allow_blank=True, allow_null=True)
|
|
|
item_id = serializers.CharField(required=True)
|
|
|
mandatory_attrs = serializers.DictField(
|
|
|
child=serializers.ListField(child=serializers.CharField()),
|
|
|
@@ -123,6 +246,17 @@ class SingleProductRequestSerializer(serializers.Serializer):
|
|
|
model = serializers.CharField(required=False, default="llama-3.1-8b-instant")
|
|
|
extract_additional = serializers.BooleanField(required=False, default=True)
|
|
|
process_image = serializers.BooleanField(required=False, default=True)
|
|
|
+ multiple = serializers.ListField(
|
|
|
+ child=serializers.CharField(),
|
|
|
+ required=False,
|
|
|
+ default=list,
|
|
|
+ help_text="List of attribute names that can have multiple values"
|
|
|
+ )
|
|
|
+ threshold_abs = serializers.FloatField(default=0.65, required=False)
|
|
|
+ margin = serializers.FloatField(default=0.15, required=False)
|
|
|
+ use_dynamic_thresholds = serializers.BooleanField(default=True, required=False)
|
|
|
+ use_adaptive_margin = serializers.BooleanField(default=True, required=False)
|
|
|
+ use_semantic_clustering = serializers.BooleanField(default=True, required=False)
|
|
|
|
|
|
def validate_model(self, value):
|
|
|
from django.conf import settings
|
|
|
@@ -133,19 +267,28 @@ class SingleProductRequestSerializer(serializers.Serializer):
|
|
|
return value
|
|
|
|
|
|
|
|
|
-
|
|
|
class BatchProductRequestSerializer(serializers.Serializer):
|
|
|
"""Serializer for batch product extraction request (with item-specific attributes)."""
|
|
|
products = serializers.ListField(
|
|
|
- child=ProductBatchInputSerializer(), # <--- Changed
|
|
|
+ child=ProductBatchInputSerializer(),
|
|
|
required=True,
|
|
|
min_length=1
|
|
|
)
|
|
|
model = serializers.CharField(required=False, default="llama-3.1-8b-instant")
|
|
|
extract_additional = serializers.BooleanField(required=False, default=True)
|
|
|
process_image = serializers.BooleanField(required=False, default=True)
|
|
|
+ multiple = serializers.ListField(
|
|
|
+ child=serializers.CharField(),
|
|
|
+ required=False,
|
|
|
+ default=list,
|
|
|
+ help_text="List of attribute names that can have multiple values"
|
|
|
+ )
|
|
|
+ threshold_abs = serializers.FloatField(default=0.65, required=False)
|
|
|
+ margin = serializers.FloatField(default=0.15, required=False)
|
|
|
+ use_dynamic_thresholds = serializers.BooleanField(default=True, required=False)
|
|
|
+ use_adaptive_margin = serializers.BooleanField(default=True, required=False)
|
|
|
+ use_semantic_clustering = serializers.BooleanField(default=True, required=False)
|
|
|
|
|
|
- # ... validate_model method ...
|
|
|
def validate_model(self, value):
|
|
|
from django.conf import settings
|
|
|
if value not in settings.SUPPORTED_MODELS:
|
|
|
@@ -154,7 +297,6 @@ class BatchProductRequestSerializer(serializers.Serializer):
|
|
|
)
|
|
|
return value
|
|
|
|
|
|
- # ... validate_products method (updated to use products instead of item_ids) ...
|
|
|
def validate_products(self, value):
|
|
|
from django.conf import settings
|
|
|
max_size = getattr(settings, 'MAX_BATCH_SIZE', 100)
|
|
|
@@ -164,6 +306,7 @@ class BatchProductRequestSerializer(serializers.Serializer):
|
|
|
)
|
|
|
return value
|
|
|
|
|
|
+
|
|
|
class OCRResultSerializer(serializers.Serializer):
|
|
|
"""Serializer for OCR results."""
|
|
|
detected_text = serializers.ListField(child=serializers.DictField())
|
|
|
@@ -188,12 +331,8 @@ class BatchProductResponseSerializer(serializers.Serializer):
|
|
|
failed = serializers.IntegerField()
|
|
|
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-from rest_framework import serializers
|
|
|
-from .models import Product
|
|
|
-
|
|
|
class ProductSerializer(serializers.ModelSerializer):
|
|
|
+ """Serializer for Product model with product type details."""
|
|
|
product_type_details = serializers.SerializerMethodField()
|
|
|
|
|
|
class Meta:
|
|
|
@@ -207,11 +346,11 @@ class ProductSerializer(serializers.ModelSerializer):
|
|
|
'product_type',
|
|
|
'image_path',
|
|
|
'image',
|
|
|
- 'product_type_details', # new field
|
|
|
+ 'product_type_details',
|
|
|
]
|
|
|
|
|
|
def get_product_type_details(self, obj):
|
|
|
- # Fetch ProductType object for this product
|
|
|
+ """Fetch ProductType object and its attributes for this product."""
|
|
|
try:
|
|
|
product_type = ProductType.objects.get(name=obj.product_type)
|
|
|
except ProductType.DoesNotExist:
|
|
|
@@ -229,25 +368,34 @@ class ProductSerializer(serializers.ModelSerializer):
|
|
|
]
|
|
|
|
|
|
|
|
|
-
|
|
|
-from rest_framework import serializers
|
|
|
-from .models import Product, ProductType, ProductAttribute, AttributePossibleValue
|
|
|
-
|
|
|
class AttributePossibleValueSerializer(serializers.ModelSerializer):
|
|
|
+ """Serializer for AttributePossibleValue model."""
|
|
|
class Meta:
|
|
|
model = AttributePossibleValue
|
|
|
fields = ['value']
|
|
|
|
|
|
+
|
|
|
class ProductAttributeSerializer(serializers.ModelSerializer):
|
|
|
+ """Serializer for ProductAttribute model with possible values."""
|
|
|
possible_values = AttributePossibleValueSerializer(many=True, read_only=True)
|
|
|
|
|
|
class Meta:
|
|
|
model = ProductAttribute
|
|
|
fields = ['name', 'is_mandatory', 'possible_values']
|
|
|
|
|
|
+
|
|
|
class ProductTypeSerializer(serializers.ModelSerializer):
|
|
|
+ """Serializer for ProductType model with attributes."""
|
|
|
attributes = ProductAttributeSerializer(many=True, read_only=True)
|
|
|
|
|
|
class Meta:
|
|
|
model = ProductType
|
|
|
fields = ['name', 'attributes']
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|