Source code for members.models.membership

from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
from django.utils import timezone
from django.utils.translation import pgettext_lazy, gettext_lazy as _

from utils.snippets import overlaps


[docs]class Membership(models.Model): MEMBER = "member" BENEFACTOR = "benefactor" HONORARY = "honorary" MEMBERSHIP_TYPES = ( (MEMBER, _("Member")), (BENEFACTOR, _("Benefactor")), (HONORARY, _("Honorary Member")), ) type = models.CharField( max_length=40, choices=MEMBERSHIP_TYPES, verbose_name=_("Membership type"), ) user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_("User"), ) since = models.DateField( verbose_name=_("Membership since"), help_text=_("The date the member started holding this membership."), default=timezone.now, ) until = models.DateField( verbose_name=_("Membership until"), help_text=_("The date the member stops holding this membership."), blank=True, null=True, ) def __str__(self): s = _("Membership of type {} for {} ({}) starting {}").format( self.get_type_display(), self.user.get_full_name(), self.user.username, self.since, ) if self.until is not None: s += pgettext_lazy("Membership until x", " until {}").format(self.until) return s
[docs] def clean(self): super().clean() errors = {} if self.until and (not self.since or self.until < self.since): raise ValidationError({"until": _("End date can't be before start date")}) if self.since is not None: memberships = self.user.membership_set.all() if overlaps(self, memberships): errors.update( { "since": _("A membership already exists for that period"), "until": _("A membership already exists for that period"), } ) if errors: raise ValidationError(errors)
[docs] def is_active(self): return not self.until or self.until > timezone.now().date()