Ejemplo n.º 1
0
class Forum(models.Model):
    """
    A Forum, containing Topics. It can be public or restricted to some groups.
    """
    class Meta:
        verbose_name = 'Forum'
        verbose_name_plural = 'Forums'
        ordering = ['position_in_category', 'title']

    title = models.CharField('Titre', max_length=80)
    subtitle = models.CharField('Sous-titre', max_length=200)

    # Groups authorized to read this forum. If no group is defined, the forum is public (and anyone can read it).
    group = models.ManyToManyField(
        Group,
        verbose_name='Groupe autorisés (Aucun = public)',
        blank=True)

    category = models.ForeignKey(Category, db_index=True, verbose_name='Catégorie')
    position_in_category = models.IntegerField('Position dans la catégorie',
                                               null=True, blank=True, db_index=True)

    slug = models.SlugField(max_length=80, unique=True)
    objects = ForumManager()

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('forum-topics-list', kwargs={'cat_slug': self.category.slug, 'forum_slug': self.slug})

    def get_topic_count(self):
        """Retrieve or agregate the number of threads in this forum. If this number already exists, it must be stored \
        in thread_count. Otherwise it will process a SQL query

        :return: the number of threads in the forum.
        """
        try:
            return self.thread_count
        except AttributeError:
            return Topic.objects.filter(forum=self).count()

    def get_post_count(self):
        """Retrieve or agregate the number of posts in this forum. If this number already exists, it must be stored \
        in post_count. Otherwise it will process a SQL query

        :return: the number of posts for a forum.
        """
        try:
            return self.post_count
        except AttributeError:
            return Post.objects.filter(topic__forum=self).count()

    def get_last_message(self):
        """
        :return: the last message on the forum, if there are any.
        """
        try:
            return Post.objects.filter(topic__forum=self).order_by('-pubdate').all()[0]
        except IndexError:
            return None

    def can_read(self, user):
        """
        Checks if an user can read current forum.
        The forum can be read if:
        - The forum has no access restriction (= no group), or
        - the user is in our database and is part of the restricted group which is needed to access this forum
        :param user: the user to check the rights
        :return: `True` if the user can read this forum, `False` otherwise.
        """

        if self.group.count() == 0:
            return True
        else:
            # authentication is the best way to be sure groups are available in the user object
            if user is not None:
                groups = list(user.groups.all()) if not isinstance(user, AnonymousUser) else []
                return Forum.objects.filter(
                    group__in=groups,
                    pk=self.pk).exists()
            else:
                return False
Ejemplo n.º 2
0
class Forum(models.Model):
    """
    A Forum, containing Topics. It can be public or restricted to some groups.
    """
    class Meta:
        verbose_name = "Forum"
        verbose_name_plural = "Forums"
        ordering = ["position_in_category", "title"]

    title = models.CharField("Titre", max_length=80)
    subtitle = models.CharField("Sous-titre", max_length=200)

    # Groups authorized to read this forum. If no group is defined, the forum is public (and anyone can read it).
    groups = models.ManyToManyField(
        Group, verbose_name="Groupes autorisés (aucun = public)", blank=True)

    # better handling of on_delete with SET(value)?
    category = models.ForeignKey(ForumCategory,
                                 db_index=True,
                                 verbose_name="Catégorie",
                                 on_delete=models.CASCADE)
    position_in_category = models.IntegerField("Position dans la catégorie",
                                               null=True,
                                               blank=True,
                                               db_index=True)

    slug = models.SlugField(max_length=80, unique=True)
    _nb_group = None
    objects = ForumManager()

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("forum-topics-list",
                       kwargs={
                           "cat_slug": self.category.slug,
                           "forum_slug": self.slug
                       })

    def get_topic_count(self):
        """Retrieve or aggregate the number of threads in this forum. If this number already exists, it must be stored \
        in thread_count. Otherwise it will process a SQL query.

        :return: the number of threads in the forum.
        """
        try:
            return self.thread_count
        except AttributeError:
            return Topic.objects.filter(forum=self).count()

    def get_post_count(self):
        """Retrieve or aggregate the number of posts in this forum. If this number already exists, it must be stored \
        in post_count. Otherwise it will process a SQL query.

        :return: the number of posts for a forum.
        """
        try:
            return self.post_count
        except AttributeError:
            return Post.objects.filter(topic__forum=self).count()

    def get_last_message(self):
        """
        :return: the last message on the forum, if there are any.
        """
        try:
            return Post.objects.filter(
                topic__forum=self).order_by("-pubdate").all()[0]
        except IndexError:
            return None

    def can_read(self, user):
        """
        Checks if a user can read current forum.
        The forum can be read if:
        - The forum has no access restriction (= no group), or
        - the user is in our database and is part of the restricted group which is needed to access this forum
        :param user: the user to check the rights
        :return: `True` if the user can read this forum, `False` otherwise.
        """

        if not self.has_group:
            return True
        else:
            # authentication is the best way to be sure groups are available in the user object
            if user is not None:
                groups = list(user.groups.all()) if not isinstance(
                    user, AnonymousUser) else []
                return Forum.objects.filter(groups__in=groups,
                                            pk=self.pk).exists()
            else:
                return False

    @property
    def has_group(self):
        """
        Checks if this forum belongs to at least one group

        :return: ``True`` if it belongs to at least one group
        :rtype: bool
        """
        if self._nb_group is None:
            self._nb_group = self.groups.count()
        return self._nb_group > 0