from django.db import models from django.contrib.auth.models import User from django.db.models.signals import post_save from django.dispatch import receiver import os from .utils import process_clothing_image class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') avatar = models.ImageField(upload_to='avatars/', null=True, blank=True) def __str__(self): return f"{self.user.username}'s Profile" @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: UserProfile.objects.get_or_create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): if not hasattr(instance, 'profile'): UserProfile.objects.create(user=instance) instance.profile.save() class Category(models.Model): TYPE_CHOICES = [ ('wardrobe', 'Wardrobe'), ('accessory', 'Accessory'), ] name = models.CharField(max_length=100) item_type = models.CharField(max_length=20, choices=TYPE_CHOICES) is_preset = models.BooleanField(default=False) parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children') def __get_full_path(self): if self.parent: return f"{self.parent.__get_full_path()} > {self.name}" return self.name def __str__(self): return f"{self.__get_full_path()} ({self.get_item_type_display()})" class Meta: verbose_name_plural = "Categories" class WardrobeItem(models.Model): SEASON_CHOICES = [ ('summer', 'Summer'), ('spring', 'Spring'), ('autumn', 'Autumn'), ('winter', 'Winter'), ] name = models.CharField(max_length=255, blank=True, null=True) category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True, related_name='wardrobe_items') image = models.ImageField(upload_to='wardrobe/') season = models.CharField(max_length=20, choices=SEASON_CHOICES, blank=True, null=True) date_added = models.DateTimeField(auto_now_add=True) def save(self, *args, **kwargs): is_new = self.pk is None super().save(*args, **kwargs) if is_new and self.image: process_clothing_image(self.image.path) def __str__(self): return self.name or f"Wardrobe Item {self.id}" class Accessory(models.Model): SEASON_CHOICES = [ ('summer', 'Summer'), ('spring', 'Spring'), ('autumn', 'Autumn'), ('winter', 'Winter'), ] name = models.CharField(max_length=255, blank=True, null=True) category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True, related_name='accessories') image = models.ImageField(upload_to='accessories/') season = models.CharField(max_length=20, choices=SEASON_CHOICES, blank=True, null=True) date_added = models.DateTimeField(auto_now_add=True) def save(self, *args, **kwargs): is_new = self.pk is None super().save(*args, **kwargs) if is_new and self.image: process_clothing_image(self.image.path) def __str__(self): return self.name or f"Accessory {self.id}" class Meta: verbose_name_plural = "Accessories" class OutfitFolder(models.Model): name = models.CharField(max_length=100) parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children') is_preset = models.BooleanField(default=False) def __str__(self): if self.parent: return f"{self.parent} > {self.name}" return self.name class Outfit(models.Model): SEASON_CHOICES = [ ('summer', 'Summer'), ('spring', 'Spring'), ('autumn', 'Autumn'), ('winter', 'Winter'), ] name = models.CharField(max_length=255, blank=True, null=True) season = models.CharField(max_length=20, choices=SEASON_CHOICES, blank=True, null=True) folder = models.ForeignKey(OutfitFolder, on_delete=models.SET_NULL, null=True, blank=True, related_name='outfits') items = models.ManyToManyField(WardrobeItem, related_name='outfits', blank=True) accessories = models.ManyToManyField(Accessory, related_name='outfits', blank=True) date_created = models.DateTimeField(auto_now_add=True) def __str__(self): return self.name or f"Outfit {self.id}" class CalendarAssignment(models.Model): date = models.DateField(unique=True) outfit = models.ForeignKey(Outfit, on_delete=models.CASCADE, related_name='assignments') def __str__(self): return f"{self.date}: {self.outfit}"