Files
GNX-WEB/backEnd/services/models.py
Iliyan Angelov 366f28677a update
2025-11-24 03:52:08 +02:00

186 lines
6.1 KiB
Python

from django.db import models
from django.utils import timezone
from django.core.validators import MinValueValidator
from django.utils.text import slugify
import os
def service_image_upload_path(instance, filename):
"""
Generate upload path for service images
"""
# Get file extension
ext = filename.split('.')[-1]
# Create filename with service slug
filename = f"{instance.slug}.{ext}"
return os.path.join('services', 'images', filename)
class Service(models.Model):
"""
Service model for the services page
"""
title = models.CharField(max_length=200, help_text="Service title")
description = models.TextField(help_text="Service description")
slug = models.SlugField(max_length=200, unique=True, help_text="URL-friendly version of the title")
icon = models.CharField(max_length=50, help_text="Icon name (e.g., 'code', 'api', 'cloud')")
image = models.ImageField(
upload_to=service_image_upload_path,
blank=True,
null=True,
help_text="Service image"
)
image_url = models.CharField(
max_length=500,
blank=True,
help_text="External image URL (alternative to uploaded image)"
)
price = models.DecimalField(
max_digits=10,
decimal_places=2,
validators=[MinValueValidator(0)],
help_text="Service price"
)
category = models.ForeignKey(
'ServiceCategory',
on_delete=models.SET_NULL,
null=True,
blank=True,
help_text="Service category"
)
short_description = models.CharField(
max_length=300,
blank=True,
help_text="Short description for cards and previews"
)
duration = models.CharField(
max_length=100,
blank=True,
help_text="Project duration (e.g., '2-4 weeks', '3-6 months')"
)
deliverables = models.TextField(
blank=True,
help_text="What you get with this service"
)
technologies = models.TextField(
blank=True,
help_text="Technologies and tools used"
)
process_steps = models.TextField(
blank=True,
help_text="Process steps in JSON format or comma-separated"
)
features_description = models.TextField(
blank=True,
help_text="Description for the Key Features section"
)
deliverables_description = models.TextField(
blank=True,
help_text="Description for the What You Get section"
)
process_description = models.TextField(
blank=True,
help_text="Description for the Our Process section"
)
why_choose_description = models.TextField(
blank=True,
help_text="Description for the Why Choose Our Service section"
)
expertise_description = models.TextField(
blank=True,
help_text="Description for the Our Expertise section"
)
featured = models.BooleanField(default=False, help_text="Whether this service is featured")
display_order = models.PositiveIntegerField(default=0, help_text="Order for displaying services")
is_active = models.BooleanField(default=True, help_text="Whether this service is active")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['display_order', 'created_at']
verbose_name = "Service"
verbose_name_plural = "Services"
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super().save(*args, **kwargs)
@property
def formatted_price(self):
"""Return formatted price as string"""
return f"${self.price:,.2f}"
@property
def get_image_url(self):
"""Return the image URL (uploaded image or external URL)"""
if self.image and hasattr(self.image, 'url'):
return self.image.url
elif self.image_url:
return self.image_url
return None
class ServiceFeature(models.Model):
"""
Additional features for services
"""
service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name='features')
title = models.CharField(max_length=200, help_text="Feature title")
description = models.TextField(blank=True, help_text="Feature description")
icon = models.CharField(max_length=50, blank=True, help_text="Feature icon")
display_order = models.PositiveIntegerField(default=0, help_text="Order for displaying features")
class Meta:
ordering = ['display_order', 'title']
verbose_name = "Service Feature"
verbose_name_plural = "Service Features"
def __str__(self):
return f"{self.service.title} - {self.title}"
class ServiceExpertise(models.Model):
"""
Expertise items for the "Our Expertise" section
"""
service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name='expertise_items')
title = models.CharField(max_length=200, help_text="Expertise title")
description = models.TextField(help_text="Expertise description")
icon = models.CharField(max_length=50, blank=True, help_text="Expertise icon")
display_order = models.PositiveIntegerField(default=0, help_text="Order for displaying expertise items")
class Meta:
ordering = ['display_order', 'title']
verbose_name = "Service Expertise"
verbose_name_plural = "Service Expertise Items"
def __str__(self):
return f"{self.service.title} - {self.title}"
class ServiceCategory(models.Model):
"""
Categories for services
"""
name = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
description = models.TextField(blank=True)
display_order = models.PositiveIntegerField(default=0)
is_active = models.BooleanField(default=True)
class Meta:
ordering = ['display_order', 'name']
verbose_name = "Service Category"
verbose_name_plural = "Service Categories"
def __str__(self):
return self.name
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
super().save(*args, **kwargs)