models.py 4.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # models.py
  2. from django.db import models
  3. # Note: JSONField is automatically used for PostgreSQL by Django 3.1+
  4. # If using an older Django, you might need: from django.contrib.postgres.fields import JSONField
  5. class Product(models.Model):
  6. """Product model to store basic product information"""
  7. sku = models.CharField(max_length=100, unique=True)
  8. category = models.CharField(max_length=100)
  9. title = models.TextField()
  10. description = models.TextField(blank=True)
  11. # New fields for completeness (optional, but good practice)
  12. short_description = models.TextField(blank=True)
  13. seo_title = models.CharField(max_length=255, blank=True)
  14. seo_description = models.TextField(blank=True)
  15. attributes = models.JSONField(default=dict)
  16. created_at = models.DateTimeField(auto_now_add=True)
  17. updated_at = models.DateTimeField(auto_now=True)
  18. image_path = models.TextField(blank=True)
  19. class Meta:
  20. indexes = [
  21. models.Index(fields=['category']),
  22. models.Index(fields=['sku']),
  23. ]
  24. def __str__(self):
  25. return f"{self.sku} - {self.title}"
  26. # ... AttributeScore model remains the same ...
  27. class AttributeScore(models.Model):
  28. """Store attribute quality scores"""
  29. product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='attribute_scores')
  30. score = models.FloatField()
  31. max_score = models.FloatField(default=100.0)
  32. details = models.JSONField(default=dict)
  33. issues = models.JSONField(default=list)
  34. suggestions = models.JSONField(default=list)
  35. ai_suggestions = models.JSONField(default=dict, blank=True) # Gemini AI suggestions
  36. processing_time = models.FloatField(null=True, blank=True)
  37. created_at = models.DateTimeField(auto_now_add=True)
  38. class Meta:
  39. indexes = [
  40. models.Index(fields=['-created_at']),
  41. ]
  42. def __str__(self):
  43. return f"{self.product.sku} - Score: {self.score}/{self.max_score}"
  44. # ... CategoryAttributeRule model remains the same ...
  45. class CategoryAttributeRule(models.Model):
  46. """Define mandatory attributes per category"""
  47. category = models.CharField(max_length=100)
  48. attribute_name = models.CharField(max_length=100)
  49. is_mandatory = models.BooleanField(default=False)
  50. valid_values = models.JSONField(default=list, blank=True)
  51. data_type = models.CharField(max_length=50, default='string')
  52. validation_regex = models.CharField(max_length=500, blank=True)
  53. min_length = models.IntegerField(null=True, blank=True)
  54. max_length = models.IntegerField(null=True, blank=True)
  55. description = models.TextField(blank=True)
  56. class Meta:
  57. unique_together = ('category', 'attribute_name')
  58. indexes = [
  59. models.Index(fields=['category']),
  60. ]
  61. def __str__(self):
  62. return f"{self.category} - {self.attribute_name}"
  63. # --- NEW MODEL FOR CONTENT RULES ---
  64. class ProductContentRule(models.Model):
  65. """Define rules for general product content fields (title, description, SEO)"""
  66. category = models.CharField(max_length=100, blank=True, null=True, help_text="Category or NULL for a global rule.")
  67. field_name = models.CharField(max_length=100, help_text="e.g., 'title', 'description', 'seo_title'")
  68. is_mandatory = models.BooleanField(default=True)
  69. min_length = models.IntegerField(null=True, blank=True, help_text="Minimum character length.")
  70. max_length = models.IntegerField(null=True, blank=True, help_text="Maximum character length.")
  71. min_word_count = models.IntegerField(null=True, blank=True, help_text="Minimum word count.")
  72. max_word_count = models.IntegerField(null=True, blank=True, help_text="Maximum word count.")
  73. must_contain_keywords = models.JSONField(default=list, blank=True, help_text="List of keywords (case-insensitive) that must be present.")
  74. validation_regex = models.CharField(max_length=500, blank=True, help_text="A regex to validate the field content.")
  75. description = models.TextField(blank=True)
  76. class Meta:
  77. unique_together = ('category', 'field_name')
  78. indexes = [
  79. models.Index(fields=['field_name']),
  80. models.Index(fields=['category', 'field_name']),
  81. ]
  82. def __str__(self):
  83. category_str = self.category if self.category else 'GLOBAL'
  84. return f"{category_str} - Content Rule: {self.field_name}"