Source code for oioioi.portals.models

from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.db import models
from django.dispatch import Signal

from django.utils.translation import get_language, get_language_from_request
from django.utils.translation import gettext_lazy as _
from mptt.models import MPTTModel, TreeForeignKey

from oioioi.base.utils.validators import validate_db_string_id, validate_whitespaces

if (
    'oioioi.portals.processors.portal_processor'
    not in settings.TEMPLATES[0]['OPTIONS']['context_processors']
):
    raise ImproperlyConfigured(
        "When using portals module "
        "you have to add oioioi.portals.processors.portal_processor "
        "to TEMPLATES[0]['OPTIONS']['context_processors'] in settings.py"
    )



[docs]class Node(MPTTModel):
[docs] short_name = models.CharField( max_length=32, verbose_name=_("short name"), help_text=_("Shown in the URL."), validators=[validate_db_string_id], )
[docs] parent = TreeForeignKey( 'self', null=True, blank=False, related_name='children', verbose_name=_("parent"), on_delete=models.CASCADE, )
[docs] problems_in_content = models.ManyToManyField( 'problems.problem', related_name='portal_pages', blank=True )
[docs] class Meta(object):
[docs] unique_together = ('parent', 'short_name')
[docs] def __str__(self): return str(self.get_lang_version().full_name)
[docs] def get_lang_version(self, request=None): """Tries to get a default language version for a current context (from a given request, then a current thread and then from the settings). If none matching version could be found, just return any. """ languages = [get_language_from_request(request)] if request is not None else [] languages += [get_language(), settings.LANGUAGE_CODE] for lang in languages: try: return self.language_versions.get(language=lang) except NodeLanguageVersion.DoesNotExist: pass return self.language_versions.first()
[docs] def get_siblings(self, include_self=False): """Wrapper around mptt get_siblings method. Does not consider two root nodes to be siblings. """ if self.is_root_node(): if include_self: return Node.objects.filter(pk=self.pk) else: return Node.objects.none() else: return super(Node, self).get_siblings(include_self)
[docs] def get_path(self): return '/'.join( node.short_name for node in self.get_ancestors(include_self=True) ).lstrip('/')
[docs]class NodeLanguageVersion(models.Model):
[docs] node = models.ForeignKey( Node, related_name='language_versions', on_delete=models.CASCADE )
[docs] language = models.CharField(max_length=6, verbose_name=_("language code"))
[docs] full_name = models.CharField( max_length=32, verbose_name=_("full name"), help_text=_("Shown in the navigation menu."), validators=[validate_whitespaces], )
[docs] panel_code = models.TextField(null=False, blank=True, verbose_name=_("panel code"))
[docs] class Meta(object):
[docs] unique_together = ('node', 'language')
[docs]class Portal(models.Model):
[docs] owner = models.OneToOneField(User, null=True, unique=True, on_delete=models.CASCADE)
[docs] root = models.OneToOneField(Node, unique=True, on_delete=models.CASCADE)
[docs] short_description = models.CharField( max_length=256, null=True, default=_("My portal."), verbose_name=_("short description"), )
[docs] is_public = models.BooleanField(default=False, verbose_name=_("is public"))
[docs] def clean(self): super(Portal, self).clean() if (self.owner is None) == (self.link_name is None): # !xor raise ValidationError( _("Exactly one from the following should be chosen: owner, link_name") )