Example #1
0
class Material(LocalizedModel):
    objects = MaterialQuerySet.as_manager()

    class Meta:
        ordering = ['-highlight', '-timestamp']
        verbose_name = _("Material")
        verbose_name_plural = _("Materials")

    title = LocalizedCharField(blank=False,
                               null=False,
                               required=False,
                               max_length=512,
                               verbose_name=_("title"))
    slug = LocalizedUniqueSlugField(populate_from='title')
    timestamp = models.DateTimeField(auto_now_add=True,
                                     verbose_name=_("creation timestamp"))
    highlight = models.BooleanField(default=False,
                                    verbose_name=_("highlighted on search"))

    subjects = models.ManyToManyField(Subject, verbose_name=_("subject"))
    goal = LocalizedTextField(blank=True,
                              null=True,
                              required=False,
                              verbose_name=_("goal"))
    brief = LocalizedTextField(blank=False,
                               null=False,
                               required=False,
                               verbose_name=_("brief"))
    author = models.CharField(max_length=512,
                              blank=True,
                              verbose_name=_("author"))

    def __str__(self):
        return str(self.title)

    @property
    def brief_rendered(self):
        return markdownify(str(self.brief))

    @property
    def goal_rendered(self):
        return markdownify(str(self.goal))

    def get_related(self):
        for related in ['activity', 'reading', 'video', 'link']:
            if hasattr(self, related):
                return getattr(self, related)

    def get_model_name(self):
        return self.get_related()._meta.model_name

    def get_absolute_url(self):
        return self.get_related().get_absolute_url()
Example #2
0
class Interest(UUIDModel, HistoricalModel):
    title = LocalizedCharField()
    description = LocalizedTextField(blank=True, null=True, required=False)
    category = models.ForeignKey(InterestCategory,
                                 related_name="interests",
                                 on_delete=models.PROTECT)
    archived = models.BooleanField(default=False)
Example #3
0
class Permission(SlugModel):
    name = LocalizedCharField(_("permission name"),
                              blank=False,
                              null=False,
                              required=False)
    description = LocalizedTextField(_("permission description"),
                                     null=True,
                                     blank=True,
                                     required=False)
Example #4
0
class Tag(SlugModel):
    name = models.CharField(_("tag name"),
                            blank=False,
                            null=False,
                            max_length=100)
    description = LocalizedTextField(_("tag description"),
                                     null=True,
                                     blank=True,
                                     required=False)
Example #5
0
class Category(SlugModel):
    name = LocalizedCharField(
        _("category name"), blank=False, null=False, required=False
    )
    description = LocalizedTextField(
        _("category description"), null=True, blank=True, required=False
    )
    color = models.CharField(
        max_length=18, default="#FFFFFF", validators=[color_validator],
    )
Example #6
0
class Role(SlugModel):
    name = LocalizedCharField(_("role name"),
                              blank=False,
                              null=False,
                              required=False)
    description = LocalizedTextField(_("role description"),
                                     null=True,
                                     blank=True,
                                     required=False)
    permissions = models.ManyToManyField("Permission", related_name="roles")

    class Meta:
        ordering = ["slug"]
Example #7
0
class Chunk(models.Model):
    class Meta:
        ordering = ['slug']
        verbose_name = _("Chunk")
        verbose_name_plural = _("Chunks")

    slug = models.SlugField(unique=True, verbose_name=_("slug"))
    content = LocalizedTextField(blank=False,
                                 null=False,
                                 required=False,
                                 verbose_name=_("content"))

    def __str__(self):
        return str(self.slug)
Example #8
0
class Document(UUIDModel):
    title = LocalizedCharField(
        _("document title"), blank=True, null=True, required=False
    )
    description = LocalizedTextField(
        _("document description"), null=True, blank=True, required=False
    )
    category = models.ForeignKey(
        Category,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="documents",
    )
    tags = models.ManyToManyField(Tag, blank=True, related_name="documents")
Example #9
0
class Scope(MPTTModel, UUIDModel):
    name = LocalizedCharField(_("scope name"),
                              blank=False,
                              null=False,
                              required=False)
    description = LocalizedTextField(_("scope description"),
                                     null=True,
                                     blank=True,
                                     required=False)
    parent = TreeForeignKey(
        "self",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="children",
    )
Example #10
0
class Activity(Material):
    objects = MaterialQuerySet.as_manager()

    class Meta:
        ordering = ['-timestamp']
        verbose_name = _("Activity")
        verbose_name_plural = _("Activities")

    location = models.ForeignKey(Location,
                                 null=True,
                                 blank=True,
                                 on_delete=models.SET_NULL,
                                 verbose_name=_("location"))

    duration = models.PositiveSmallIntegerField(
        null=True,
        blank=True,
        verbose_name=_("duration"),
        help_text=_("Duration in minutes."),
    )

    num_people = IntegerRangeField(default=NumericRange(2, 30),
                                   verbose_name=_("number of people"))

    group_feature = models.ForeignKey(GroupFeature,
                                      null=True,
                                      blank=True,
                                      on_delete=models.SET_NULL,
                                      verbose_name=_("group feature"))
    notes = LocalizedTextField(null=True, blank=True, verbose_name=_("notes"))
    attachment = models.FileField(upload_to='material/activities/',
                                  blank=True,
                                  verbose_name=_("attachment"))
    url = models.URLField(
        blank=True,
        verbose_name=_("URL"),
        help_text=_(
            "Link the material if its copyright does not allow sharing it."))

    def get_absolute_url(self):
        return reverse('material:detail-activity', kwargs={'slug': self.slug})

    def clean(self):
        if self.num_people.lower < 1:
            raise ValidationError(_("The lower bound must be at least 1."),
                                  code='invalid')
Example #11
0
class Membership(UUIDModel, HistoricalModel):
    identity = models.ForeignKey(
        "Identity",
        on_delete=models.CASCADE,
        related_name="members",
    )
    organisation = models.ForeignKey(
        "Identity",
        on_delete=models.CASCADE,
        related_name="memberships",
    )
    role = models.ForeignKey(
        MembershipRole,
        related_name="memberships",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
    )
    authorized = models.BooleanField(default=False)
    time_slot = DateRangeField(null=True, blank=True)
    next_election = models.DateField(null=True, blank=True)
    comment = LocalizedTextField(blank=True, null=True, required=False)
    inactive = models.BooleanField(default=False)
Example #12
0
class Question(SlugModel):
    TYPE_MULTIPLE_CHOICE = "multiple_choice"
    TYPE_INTEGER = "integer"
    TYPE_FLOAT = "float"
    TYPE_DATE = "date"
    TYPE_CHOICE = "choice"
    TYPE_TEXTAREA = "textarea"
    TYPE_TEXT = "text"
    TYPE_TABLE = "table"
    TYPE_FORM = "form"
    TYPE_FILE = "file"
    TYPE_DYNAMIC_CHOICE = "dynamic_choice"
    TYPE_DYNAMIC_MULTIPLE_CHOICE = "dynamic_multiple_choice"
    TYPE_STATIC = "static"

    TYPE_CHOICES = (
        TYPE_MULTIPLE_CHOICE,
        TYPE_INTEGER,
        TYPE_FLOAT,
        TYPE_DATE,
        TYPE_CHOICE,
        TYPE_TEXTAREA,
        TYPE_TEXT,
        TYPE_TABLE,
        TYPE_FORM,
        TYPE_FILE,
        TYPE_DYNAMIC_CHOICE,
        TYPE_DYNAMIC_MULTIPLE_CHOICE,
        TYPE_STATIC,
    )
    TYPE_CHOICES_TUPLE = ((type_choice, type_choice) for type_choice in TYPE_CHOICES)

    label = LocalizedField(blank=False, null=False, required=False)
    type = models.CharField(choices=TYPE_CHOICES_TUPLE, max_length=23)
    is_required = models.TextField(default="false")
    is_hidden = models.TextField(default="false")
    is_archived = models.BooleanField(default=False)
    placeholder = LocalizedField(blank=True, null=True, required=False)
    info_text = LocalizedField(blank=True, null=True, required=False)
    static_content = LocalizedTextField(blank=True, null=True, required=False)
    configuration = JSONField(default=dict)
    meta = JSONField(default=dict)
    data_source = models.CharField(max_length=255, blank=True, null=True)
    options = models.ManyToManyField(
        "Option", through="QuestionOption", related_name="questions"
    )
    row_form = models.ForeignKey(
        Form,
        blank=True,
        null=True,
        related_name="+",
        help_text="Form that represents rows of a TableQuestion",
    )
    sub_form = models.ForeignKey(
        Form,
        blank=True,
        null=True,
        related_name="+",
        help_text="Form referenced in a FormQuestion",
    )

    source = models.ForeignKey(
        "self",
        blank=True,
        null=True,
        related_name="+",
        help_text="Reference this question has been copied from",
    )
    format_validators = ArrayField(
        models.CharField(max_length=255), blank=True, default=list
    )

    @property
    def max_length(self):
        return self.configuration.get("max_length")

    @max_length.setter
    def max_length(self, value):
        self.configuration["max_length"] = value

    @property
    def max_value(self):
        return self.configuration.get("max_value")

    @max_value.setter
    def max_value(self, value):
        self.configuration["max_value"] = value

    @property
    def min_value(self):
        return self.configuration.get("min_value")

    @min_value.setter
    def min_value(self, value):
        self.configuration["min_value"] = value
Example #13
0
class Question(core_models.SlugModel):
    TYPE_MULTIPLE_CHOICE = "multiple_choice"
    TYPE_INTEGER = "integer"
    TYPE_FLOAT = "float"
    TYPE_DATE = "date"
    TYPE_CHOICE = "choice"
    TYPE_TEXTAREA = "textarea"
    TYPE_TEXT = "text"
    TYPE_TABLE = "table"
    TYPE_FORM = "form"
    TYPE_FILE = "file"
    TYPE_DYNAMIC_CHOICE = "dynamic_choice"
    TYPE_DYNAMIC_MULTIPLE_CHOICE = "dynamic_multiple_choice"
    TYPE_STATIC = "static"
    TYPE_CALCULATED_FLOAT = "calculated_float"

    TYPE_CHOICES = (
        TYPE_MULTIPLE_CHOICE,
        TYPE_INTEGER,
        TYPE_FLOAT,
        TYPE_DATE,
        TYPE_CHOICE,
        TYPE_TEXTAREA,
        TYPE_TEXT,
        TYPE_TABLE,
        TYPE_FORM,
        TYPE_FILE,
        TYPE_DYNAMIC_CHOICE,
        TYPE_DYNAMIC_MULTIPLE_CHOICE,
        TYPE_STATIC,
        TYPE_CALCULATED_FLOAT,
    )
    TYPE_CHOICES_TUPLE = ((type_choice, type_choice)
                          for type_choice in TYPE_CHOICES)

    label = LocalizedField(blank=False, null=False, required=False)
    type = models.CharField(choices=TYPE_CHOICES_TUPLE, max_length=23)
    is_required = models.TextField(default="false")
    is_hidden = models.TextField(default="false")
    is_archived = models.BooleanField(default=False)
    placeholder = LocalizedField(blank=True, null=True, required=False)
    info_text = LocalizedField(blank=True, null=True, required=False)
    static_content = LocalizedTextField(blank=True, null=True, required=False)
    configuration = JSONField(default=dict)
    meta = JSONField(default=dict)
    data_source = models.CharField(max_length=255, blank=True, null=True)
    options = models.ManyToManyField("Option",
                                     through="QuestionOption",
                                     related_name="questions")
    row_form = models.ForeignKey(
        Form,
        blank=True,
        null=True,
        related_name="+",
        help_text="Form that represents rows of a TableQuestion",
        on_delete=models.PROTECT,
    )
    sub_form = models.ForeignKey(
        Form,
        blank=True,
        null=True,
        related_name="+",
        help_text="Form referenced in a FormQuestion",
        on_delete=models.PROTECT,
    )

    source = models.ForeignKey(
        "self",
        blank=True,
        null=True,
        related_name="+",
        help_text="Reference this question has been copied from",
        on_delete=models.SET_NULL,
    )
    format_validators = ArrayField(models.CharField(max_length=255),
                                   blank=True,
                                   default=list)

    default_answer = models.OneToOneField("Answer",
                                          on_delete=models.SET_NULL,
                                          related_name="+",
                                          null=True,
                                          blank=True)

    calc_expression = models.TextField(null=True, blank=True)
    calc_dependents = ArrayField(models.CharField(max_length=255, blank=True),
                                 default=list)

    @property
    def min_length(self):
        return self.configuration.get("min_length")

    @min_length.setter
    def min_length(self, value):
        self.configuration["min_length"] = value

    @property
    def max_length(self):
        return self.configuration.get("max_length")

    @max_length.setter
    def max_length(self, value):
        self.configuration["max_length"] = value

    @property
    def max_value(self):
        return self.configuration.get("max_value")

    @max_value.setter
    def max_value(self, value):
        self.configuration["max_value"] = value

    @property
    def min_value(self):
        return self.configuration.get("min_value")

    @min_value.setter
    def min_value(self, value):
        self.configuration["min_value"] = value

    def empty_value(self):
        """Return empty value for this question type."""

        empties = {
            Question.TYPE_MULTIPLE_CHOICE: [],
            Question.TYPE_TABLE: [],
            Question.TYPE_DYNAMIC_MULTIPLE_CHOICE: [],
        }
        return empties.get(self.type, None)

    def __repr__(self):
        base = super().__repr__()
        return base[:-1] + f", type={self.type})"

    class Meta:
        indexes = [GinIndex(fields=["meta"])]
Example #14
0
class InterestCategory(UUIDModel, HistoricalModel):
    title = LocalizedCharField()
    description = LocalizedTextField(blank=True, null=True, required=False)
    archived = models.BooleanField(default=False)
Example #15
0
class Snippet(UUIDModel, HistoricalModel):
    title = LocalizedCharField(blank=False, null=False, required=False)
    body = LocalizedTextField(blank=False, null=False, required=False)
    archived = models.BooleanField(default=False)