Coverage for apps / profiles / models.py: 96%

23 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-12 10:49 +0000

1from django.conf import settings 

2from django.db import models 

3 

4 

5AVATAR_COLORS = [ 

6 "#d97850", # burnt orange 

7 "#8fae6f", # sage green 

8 "#6b9dad", # teal 

9 "#9d80b8", # purple 

10 "#d16b6b", # coral red 

11 "#e6a05f", # amber 

12 "#6bb8a5", # mint 

13 "#c77a9e", # rose 

14 "#7d9e6f", # olive 

15 "#5b8abf", # steel blue 

16] 

17 

18 

19class Profile(models.Model): 

20 """User profile for the recipe app.""" 

21 

22 THEME_CHOICES = [ 

23 ("light", "Light"), 

24 ("dark", "Dark"), 

25 ] 

26 

27 UNIT_CHOICES = [ 

28 ("metric", "Metric"), 

29 ("imperial", "Imperial"), 

30 ] 

31 

32 user = models.OneToOneField( 

33 settings.AUTH_USER_MODEL, 

34 null=True, 

35 blank=True, 

36 on_delete=models.CASCADE, 

37 related_name="profile", 

38 ) 

39 name = models.CharField(max_length=100) 

40 avatar_color = models.CharField(max_length=7) # Hex color 

41 theme = models.CharField(max_length=10, choices=THEME_CHOICES, default="light") 

42 unit_preference = models.CharField(max_length=10, choices=UNIT_CHOICES, default="metric") 

43 unlimited_ai = models.BooleanField(default=False) 

44 created_at = models.DateTimeField(auto_now_add=True) 

45 updated_at = models.DateTimeField(auto_now=True) 

46 

47 def __str__(self): 

48 return self.name 

49 

50 @classmethod 

51 def next_avatar_color(cls): 

52 """Return the next unused color from the palette, cycling if needed.""" 

53 used_colors = set(cls.objects.values_list("avatar_color", flat=True)) 

54 for color in AVATAR_COLORS: 

55 if color not in used_colors: 

56 return color 

57 # All used - cycle based on count 

58 return AVATAR_COLORS[cls.objects.count() % len(AVATAR_COLORS)] 

← Back to Dashboard