128 lines
4.5 KiB
Python
128 lines
4.5 KiB
Python
from rest_framework import serializers
|
|
from .models import Service, ServiceFeature, ServiceExpertise, ServiceCategory
|
|
from django.core.files.uploadedfile import InMemoryUploadedFile
|
|
|
|
|
|
class ServiceFeatureSerializer(serializers.ModelSerializer):
|
|
"""
|
|
Serializer for ServiceFeature model
|
|
"""
|
|
class Meta:
|
|
model = ServiceFeature
|
|
fields = ['id', 'title', 'description', 'icon', 'display_order']
|
|
|
|
|
|
class ServiceExpertiseSerializer(serializers.ModelSerializer):
|
|
"""
|
|
Serializer for ServiceExpertise model
|
|
"""
|
|
class Meta:
|
|
model = ServiceExpertise
|
|
fields = ['id', 'title', 'description', 'icon', 'display_order']
|
|
|
|
|
|
class ServiceCategorySerializer(serializers.ModelSerializer):
|
|
"""
|
|
Serializer for ServiceCategory model
|
|
"""
|
|
class Meta:
|
|
model = ServiceCategory
|
|
fields = ['id', 'name', 'slug', 'description', 'display_order']
|
|
|
|
|
|
class ServiceSerializer(serializers.ModelSerializer):
|
|
"""
|
|
Serializer for Service model
|
|
"""
|
|
features = ServiceFeatureSerializer(many=True, read_only=True)
|
|
expertise_items = ServiceExpertiseSerializer(many=True, read_only=True)
|
|
category = ServiceCategorySerializer(read_only=True)
|
|
formatted_price = serializers.ReadOnlyField()
|
|
image_url = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Service
|
|
fields = [
|
|
'id', 'title', 'description', 'short_description', 'slug', 'icon', 'image', 'image_url',
|
|
'price', 'formatted_price', 'category', 'duration', 'deliverables', 'technologies', 'process_steps',
|
|
'features_description', 'deliverables_description', 'process_description', 'why_choose_description', 'expertise_description',
|
|
'featured', 'display_order', 'is_active', 'created_at', 'updated_at', 'features', 'expertise_items'
|
|
]
|
|
read_only_fields = ['id', 'created_at', 'updated_at', 'slug']
|
|
|
|
def get_image_url(self, obj):
|
|
"""Return the image URL"""
|
|
return obj.get_image_url
|
|
|
|
|
|
class ServiceListSerializer(serializers.ModelSerializer):
|
|
"""
|
|
Simplified serializer for service lists
|
|
"""
|
|
formatted_price = serializers.ReadOnlyField()
|
|
image_url = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Service
|
|
fields = [
|
|
'id', 'title', 'description', 'short_description', 'slug', 'icon', 'image', 'image_url',
|
|
'price', 'formatted_price', 'category', 'duration', 'deliverables', 'technologies',
|
|
'process_steps', 'featured', 'display_order'
|
|
]
|
|
|
|
def get_image_url(self, obj):
|
|
"""Return the image URL"""
|
|
return obj.get_image_url
|
|
|
|
|
|
class ServiceCreateUpdateSerializer(serializers.ModelSerializer):
|
|
"""
|
|
Serializer for creating and updating services
|
|
"""
|
|
class Meta:
|
|
model = Service
|
|
fields = [
|
|
'title', 'description', 'short_description', 'icon', 'image', 'image_url', 'price',
|
|
'category', 'duration', 'deliverables', 'technologies', 'process_steps', 'featured', 'display_order', 'is_active'
|
|
]
|
|
|
|
def create(self, validated_data):
|
|
# Generate slug from title if not provided
|
|
if 'slug' not in validated_data:
|
|
validated_data['slug'] = self.generate_unique_slug(validated_data['title'])
|
|
return super().create(validated_data)
|
|
|
|
def update(self, instance, validated_data):
|
|
# If image is being updated, delete the old image
|
|
if 'image' in validated_data and instance.image:
|
|
instance.image.delete(save=False)
|
|
return super().update(instance, validated_data)
|
|
|
|
def generate_unique_slug(self, title):
|
|
"""Generate a unique slug from title"""
|
|
from django.utils.text import slugify
|
|
base_slug = slugify(title)
|
|
slug = base_slug
|
|
counter = 1
|
|
|
|
while Service.objects.filter(slug=slug).exists():
|
|
slug = f"{base_slug}-{counter}"
|
|
counter += 1
|
|
|
|
return slug
|
|
|
|
def validate(self, data):
|
|
"""Validate service data"""
|
|
# Make image_url optional for existing services
|
|
# Only require image or image_url for new services
|
|
if self.instance is None: # Creating new service
|
|
image = data.get('image')
|
|
image_url = data.get('image_url')
|
|
|
|
if not image and not image_url:
|
|
raise serializers.ValidationError(
|
|
"Either an image file or image URL must be provided for new services."
|
|
)
|
|
|
|
return data
|