22
33import datetime
44
5+ from colorfield .fields import ColorField
56from django .db import models
67from django .db .models .signals import post_save
78from django .dispatch import receiver
1314from apps .users .models import User
1415from fastly .utils import purge_url
1516
17+ DEFAULT_ACCENT_COLOR = "#0073b7"
18+
19+
20+ class ElectionKind (models .Model ):
21+ """An admin-managed category of election (Board, Packaging Council, ...).
22+
23+ Each kind carries an accent color used to visually distinguish its
24+ election pages. New kinds can be added in the Django admin without
25+ code changes.
26+ """
27+
28+ name = models .CharField (max_length = 100 , unique = True )
29+ slug = models .SlugField (max_length = 120 , unique = True , blank = True , null = True )
30+ accent_color = ColorField (default = DEFAULT_ACCENT_COLOR , help_text = "Accent color used to theme this kind's pages." )
31+
32+ class Meta :
33+ """Meta configuration for ElectionKind."""
34+
35+ ordering = ["name" ]
36+
37+ def __str__ (self ):
38+ """Return the kind name."""
39+ return self .name
40+
41+ def save (self , * args , ** kwargs ):
42+ """Generate slug from name before saving."""
43+ self .slug = slugify (self .name )
44+ super ().save (* args , ** kwargs )
45+
1646
1747class Election (models .Model ):
1848 """A PSF board election with nomination open/close dates."""
1949
2050 name = models .CharField (max_length = 100 )
2151 date = models .DateField ()
52+ kind = models .ForeignKey (
53+ ElectionKind ,
54+ null = True ,
55+ blank = True ,
56+ on_delete = models .SET_NULL ,
57+ related_name = "elections" ,
58+ )
2259 nominations_open_at = models .DateTimeField (blank = True , null = True )
2360 nominations_close_at = models .DateTimeField (blank = True , null = True )
2461 description = MarkupField (escape_html = False , markup_type = "markdown" , blank = False , null = True )
@@ -39,6 +76,11 @@ def save(self, *args, **kwargs):
3976 self .slug = slugify (self .name )
4077 super ().save (* args , ** kwargs )
4178
79+ @property
80+ def accent_color (self ):
81+ """Return the CSS accent color for this election's kind."""
82+ return self .kind .accent_color if self .kind else DEFAULT_ACCENT_COLOR
83+
4284 @property
4385 def nominations_open (self ):
4486 """Return True if the current time is within the nomination window."""
0 commit comments