Source code for newsletters.models

"""The models defined by the newsletters package"""
from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from tinymce.models import HTMLField

from utils.translation import ModelTranslateMeta, MultilingualField


[docs]class Newsletter(models.Model, metaclass=ModelTranslateMeta): """Describes a newsletter""" title = MultilingualField( models.CharField, max_length=150, verbose_name=_("Title"), help_text=_("The title is used for the email subject."), blank=False, ) date = models.DateField( verbose_name=_("Date"), help_text=_( "This date is used to extract the week of this " "newsletter, best scenario:" "always use the monday of the week the newsletter is " "for. If you leave it empty no week is shown." ), blank=True, null=True, ) send_date = models.DateTimeField( verbose_name=_("Send date"), blank=True, null=True, ) description = MultilingualField( HTMLField, verbose_name=_("Introduction"), help_text=_( "This is the text that starts the newsletter. It always " 'begins with "Dear members" and you can append ' "whatever you want." ), blank=False, ) sent = models.BooleanField(default=False)
[docs] def get_absolute_url(self): return reverse("newsletters:preview", args=(self.pk,))
[docs] def clean(self): super().clean() errors = {} url = "admin/newsletters/" if url in self.description_nl: errors.update( { "description_nl": _( "Please make sure all urls are absolute " "and contain http(s)://." ) } ) if url in self.description_en: errors.update( { "description_en": _( "Please make sure all urls are absolute " "and contain http(s)://." ) } ) if self.send_date and self.send_date <= timezone.now(): errors.update( {"send_date": _("Please make sure the send date is not in the past.")} ) if errors: raise ValidationError(errors)
[docs] def save(self, *args, **kwargs): super().save(*args, **kwargs)
class Meta: permissions = (("send_newsletter", "Can send newsletter"),) def __str__(self): return self.title
[docs]class NewsletterContent(models.Model, metaclass=ModelTranslateMeta): """Describes one piece of basic content of a newsletter""" title = MultilingualField( models.CharField, max_length=150, verbose_name=_("Title"), blank=False, null=False, ) url = models.URLField( verbose_name=_("URL"), blank=True, null=True, help_text=_("If filled, it will make the title a link to this URL"), ) description = MultilingualField( HTMLField, verbose_name=_("Description"), blank=False, null=False, ) newsletter = models.ForeignKey(Newsletter, on_delete=models.CASCADE) order = models.PositiveIntegerField( verbose_name=_("order"), blank=False, null=True, default=0 )
[docs] def clean(self): super().clean() errors = {} url = "admin/newsletters/" if url in self.description_nl: errors.update( { "description_nl": _( "Please make sure all urls are absolute " "and start with http(s)://." ) } ) if url in self.description_en: errors.update( { "description_en": _( "Please make sure all urls are absolute " "and start with http(s)://." ) } ) if errors: raise ValidationError(errors)
def __str__(self): return self.title class Meta: ordering = ("order",)
[docs]class NewsletterItem(NewsletterContent): """Describes one piece of text content of a newsletter""" pass
[docs]class NewsletterEvent(NewsletterContent): """Describes one piece of event content of a newsletter""" where = MultilingualField( models.CharField, max_length=150, verbose_name=_("Where"), blank=False, null=False, ) start_datetime = models.DateTimeField( verbose_name=_("Start date and time"), blank=False, null=False, ) end_datetime = models.DateTimeField( verbose_name=_("End date and time"), blank=False, null=False, ) show_costs_warning = models.BooleanField( verbose_name=_("Show warnings about costs"), default=True ) price = models.DecimalField( verbose_name=_("Price (in Euro)"), max_digits=5, decimal_places=2, blank=True, null=True, default=None, ) penalty_costs = models.DecimalField( verbose_name=_("Costs (in Euro)"), max_digits=5, decimal_places=2, blank=True, null=True, default=None, help_text=_( "This is the price that a member has to pay when he/she did not show up." ), )
[docs] def clean(self): """Make sure that the event end date is after the start date""" super().clean() if ( self.end_datetime is not None and self.start_datetime is not None and self.end_datetime < self.start_datetime ): raise ValidationError( {"end_datetime": _("Can't have an event travel back in time")} )