| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- # # ==================== serializers.py ====================
- # from rest_framework import serializers
- # from .models import Product, ProductType, ProductAttribute, AttributePossibleValue
- # class ProductInputSerializer(serializers.Serializer):
- # """Serializer for individual product input."""
- # product_id = 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)
- # 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."
- # )
- # class SingleProductRequestSerializer(serializers.Serializer):
- # """Serializer for single product extraction request."""
- # 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)
- # 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
- # if value not in settings.SUPPORTED_MODELS:
- # raise serializers.ValidationError(
- # f"Model must be one of {settings.SUPPORTED_MODELS}"
- # )
- # return value
- # class BatchProductRequestSerializer(serializers.Serializer):
- # """Serializer for batch product extraction request (with item-specific attributes)."""
- # products = serializers.ListField(
- # 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)
-
- # def validate_model(self, value):
- # from django.conf import settings
- # if value not in settings.SUPPORTED_MODELS:
- # raise serializers.ValidationError(
- # f"Model must be one of {settings.SUPPORTED_MODELS}"
- # )
- # return value
-
- # def validate_products(self, value):
- # from django.conf import settings
- # max_size = getattr(settings, 'MAX_BATCH_SIZE', 100)
- # if len(value) > max_size:
- # raise serializers.ValidationError(
- # f"Batch size cannot exceed {max_size} products"
- # )
- # 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)
- # class BatchProductResponseSerializer(serializers.Serializer):
- # """Serializer for batch extraction response."""
- # results = serializers.ListField(child=ProductAttributeResultSerializer())
- # total_products = serializers.IntegerField()
- # successful = serializers.IntegerField()
- # failed = serializers.IntegerField()
- # class ProductSerializer(serializers.ModelSerializer):
- # """Serializer for Product model with product type details."""
- # 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',
- # ]
- # def get_product_type_details(self, obj):
- # """Fetch ProductType object and its attributes 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
- # ]
- # 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']
-
- # ==================== Updated serializers.py ====================
- from rest_framework import serializers
- from .models import Product, ProductType, ProductAttribute, AttributePossibleValue
- class ProductInputSerializer(serializers.Serializer):
- """Serializer for individual product input."""
- product_id = 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)
- 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."
- )
- class SingleProductRequestSerializer(serializers.Serializer):
- """Serializer for single product extraction request."""
- 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)
- 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
- if value not in settings.SUPPORTED_MODELS:
- raise serializers.ValidationError(
- f"Model must be one of {settings.SUPPORTED_MODELS}"
- )
- return value
- class BatchProductRequestSerializer(serializers.Serializer):
- """Serializer for batch product extraction request (with item-specific attributes)."""
- products = serializers.ListField(
- 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)
-
- def validate_model(self, value):
- from django.conf import settings
- if value not in settings.SUPPORTED_MODELS:
- raise serializers.ValidationError(
- f"Model must be one of {settings.SUPPORTED_MODELS}"
- )
- return value
-
- def validate_products(self, value):
- from django.conf import settings
- max_size = getattr(settings, 'MAX_BATCH_SIZE', 100)
- if len(value) > max_size:
- raise serializers.ValidationError(
- f"Batch size cannot exceed {max_size} products"
- )
- return value
- class OCRResultSerializer(serializers.Serializer):
- """Serializer for OCR results."""
- detected_text = serializers.ListField(child=serializers.DictField())
- extracted_attributes = serializers.DictField()
- class VisualAttributeDetailSerializer(serializers.Serializer):
- """Serializer for detailed visual attribute predictions."""
- attribute = serializers.CharField()
- predictions = serializers.ListField(child=serializers.DictField())
- class VisualResultSerializer(serializers.Serializer):
- """Serializer for visual processing results."""
- visual_attributes = serializers.DictField(
- help_text="Extracted visual attributes like color, pattern, style, etc."
- )
- detailed_predictions = serializers.DictField(
- child=VisualAttributeDetailSerializer(),
- required=False,
- help_text="Detailed predictions with confidence scores for each attribute"
- )
- error = serializers.CharField(required=False)
- 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)
- visual_results = VisualResultSerializer(required=False)
- error = serializers.CharField(required=False)
- raw_output = serializers.CharField(required=False)
- class BatchProductResponseSerializer(serializers.Serializer):
- """Serializer for batch extraction response."""
- results = serializers.ListField(child=ProductAttributeResultSerializer())
- total_products = serializers.IntegerField()
- successful = serializers.IntegerField()
- failed = serializers.IntegerField()
- class ProductSerializer(serializers.ModelSerializer):
- """Serializer for Product model with product type details."""
- 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',
- ]
- def get_product_type_details(self, obj):
- """Fetch ProductType object and its attributes 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
- ]
- 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']
- # Add these new serializers to your serializers.py
- from rest_framework import serializers
- from .models import Product, ProductType, ProductAttribute, AttributePossibleValue, ProductAttributeValue
- class ProductAttributeValueSerializer(serializers.ModelSerializer):
- """Serializer for manually entered attribute values."""
- item_id = serializers.CharField(source='product.item_id', read_only=True)
-
- class Meta:
- model = ProductAttributeValue
- fields = ['id', 'item_id', 'attribute_name', 'original_value', 'created_at', 'updated_at']
- read_only_fields = ['created_at', 'updated_at']
- class ProductAttributeValueInputSerializer(serializers.Serializer):
- """Serializer for creating/updating attribute values."""
- item_id = serializers.CharField(required=True)
- attribute_name = serializers.CharField(required=True)
- original_value = serializers.CharField(required=True, allow_blank=True)
- class BulkProductAttributeValueSerializer(serializers.Serializer):
- """Serializer for bulk upload of attribute values."""
- item_id = serializers.CharField(required=True)
- attributes = serializers.DictField(
- child=serializers.CharField(allow_blank=True),
- required=True,
- help_text="Dictionary of attribute_name: original_value pairs"
- )
- class ProductWithAttributesSerializer(serializers.ModelSerializer):
- """Extended Product serializer with original attribute values."""
- product_type_details = serializers.SerializerMethodField()
- original_attributes = 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',
- 'original_attributes',
- ]
- def get_product_type_details(self, obj):
- """Fetch ProductType object and its attributes for this product."""
- try:
- product_type = ProductType.objects.get(name=obj.product_type)
- except ProductType.DoesNotExist:
- return []
- 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
- ]
-
- def get_original_attributes(self, obj):
- """Get manually entered original attribute values."""
- values = ProductAttributeValue.objects.filter(product=obj)
- return {val.attribute_name: val.original_value for val in values}
|