示例#1
0
class EntranceExamTaskSolution(polymorphic.models.PolymorphicModel):
    task = models.ForeignKey(
        'EntranceExamTask',
        on_delete=models.CASCADE,
        related_name='solutions',
    )

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='entrance_exam_solutions',
    )

    solution = models.TextField()

    ip = models.CharField(
        max_length=50,
        help_text='IP-адрес, с которого было отправлено решение',
        default='')

    created_at = models.DateTimeField(
        auto_now_add=True,
        db_index=True,
    )

    def __str__(self):
        return 'Решение %s по задаче %s' % (self.user, self.task)

    class Meta:
        ordering = ['-created_at']
        index_together = ('task', 'user')
示例#2
0
class ContestRegion(models.Model):
    contest = models.ForeignKey(Contest, related_name='regions')

    name = models.TextField(help_text='Region name')

    start_time = models.DateTimeField(
        help_text='Contest start time for this region')

    finish_time = models.DateTimeField(
        help_text='Contest finish time for this region')

    timezone = models.TextField(default='UTC',
                                help_text='Timezone for the region')

    def __str__(self):
        return self.name
示例#3
0
class EntranceLevelUpgradeRequirement(polymorphic.models.PolymorphicModel):
    base_level = models.ForeignKey(
        'EntranceLevel',
        on_delete=models.CASCADE,
        related_name='+',
    )

    created_at = models.DateTimeField(auto_now_add=True)

    def is_met_by_user(self, user):
        # Always met by default. Override when subclassing.
        return True
示例#4
0
class EntranceLevelUpgrade(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )

    upgraded_to = models.ForeignKey(
        'EntranceLevel',
        on_delete=models.CASCADE,
        related_name='+',
    )

    created_at = models.DateTimeField(auto_now_add=True)
示例#5
0
class GroupAccess(polymorphic.models.PolymorphicModel):
    class Type(djchoices.DjangoChoices):
        NONE = djchoices.ChoiceItem(
            value=0,
            label='Нет доступа, группа не видна',
        )

        LIST_MEMBERS = djchoices.ChoiceItem(
            value=10,
            label='Может просматривать участников',
        )
        EDIT_MEMBERS = djchoices.ChoiceItem(
            value=20,
            label='Может добавлять и удалять участников',
        )
        ADMIN = djchoices.ChoiceItem(
            value=30,
            label='Полный доступ',
        )

    to_group = models.ForeignKey(
        AbstractGroup,
        related_name='accesses',
        on_delete=models.CASCADE,
    )

    access_type = models.PositiveIntegerField(
        choices=Type.choices,
        validators=[Type.validator],
        db_index=True,
    )

    created_by = models.ForeignKey(
        users.models.User,
        related_name='+',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        help_text='Кем выдан доступ. Если None, то системой')

    created_at = models.DateTimeField(
        auto_now_add=True,
        db_index=True,
    )

    class Meta:
        verbose_name = 'group access'
        verbose_name_plural = 'group accesses'
示例#6
0
class QuestionnaireTypingDynamics(models.Model):
    user = models.ForeignKey(
        users.models.User,
        on_delete=models.CASCADE,
        related_name='+',
    )

    questionnaire = models.ForeignKey(
        Questionnaire,
        on_delete=models.CASCADE,
        related_name='+',
    )

    typing_data = sistema.models.CompressedTextField(
        help_text='JSON с данными о нажатиях клавиш')

    created_at = models.DateTimeField(auto_now_add=True)
示例#7
0
class EntranceExam(models.Model):
    school = models.OneToOneField(
        'schools.School',
        on_delete=models.CASCADE,
        related_name='entrance_exam',
    )

    close_time = models.DateTimeField(blank=True, default=None, null=True)

    def __str__(self):
        return 'Вступительная работа для %s' % self.school

    def is_closed(self):
        return (self.close_time is not None
                and django.utils.timezone.now() >= self.close_time)

    def get_absolute_url(self):
        return reverse('school:entrance:exam',
                       kwargs={'school_name': self.school.short_name})
示例#8
0
class News(ModelWithTimestamps):
    contest = models.ForeignKey(Contest, related_name='news')

    author = models.ForeignKey(users.models.User, related_name='+')

    title = models.CharField(max_length=1000, help_text='Title')

    text = models.TextField(help_text='Supports markdown')

    is_published = models.BooleanField(default=False)

    publish_time = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = 'News'

    def get_absolute_url(self):
        return urlresolvers.reverse('contests:news',
                                    args=[self.contest_id, self.id])
示例#9
0
class AbstractAbsenceReason(polymorphic.models.PolymorphicModel):
    school = models.ForeignKey('schools.School',
                               on_delete=models.CASCADE,
                               related_name='absence_reasons')

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='absence_reasons',
    )

    private_comment = models.TextField(blank=True,
                                       help_text='Не показывается школьнику')

    public_comment = models.TextField(blank=True,
                                      help_text='Показывается школьнику')

    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='+',
        null=True,
        default=None,
        blank=True,
    )

    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = 'Absence reason'

    @classmethod
    def for_user_in_school(cls, user, school):
        """
        Returns absence reason for specified user
        or None if user has not declined.
        """
        return cls.objects.filter(user=user, school=school).first()

    def default_public_comment(self):
        raise NotImplementedError()
示例#10
0
class GroupMembership(models.Model):
    group = models.ForeignKey(
        ManuallyFilledGroup,
        related_name='+',
        on_delete=models.CASCADE,
    )

    added_by = models.ForeignKey(
        users.models.User,
        null=True,
        blank=True,
        related_name='+',
        on_delete=models.CASCADE,
        help_text='Кем добавлен участник группы. None, если добавлено системой.'
    )

    created_at = models.DateTimeField(
        auto_now_add=True,
        db_index=True,
    )

    class Meta:
        abstract = True
示例#11
0
class Contest(polymorphic.models.PolymorphicModel):
    name = models.TextField(help_text='Contest name')

    is_visible_in_list = models.BooleanField(default=False)

    registration_type = models.CharField(
        max_length=20,
        choices=ContestRegistrationType.choices,
        validators=[ContestRegistrationType.validator])

    participation_mode = models.CharField(
        max_length=20,
        choices=ContestParticipationMode.choices,
        validators=[ContestParticipationMode.validator])

    start_time = models.DateTimeField(help_text='Contest start time')

    finish_time = models.DateTimeField(help_text='Contest finish time')

    registration_start_time = models.DateTimeField(
        help_text=
        'Contest registration start time, only for open and moderated registrations',
        blank=True,
        null=True)

    registration_finish_time = models.DateTimeField(
        help_text=
        'Contest registration finish time, only for open and moderated registration',
        blank=True,
        null=True)

    short_description = models.TextField(help_text='Shows on main page')

    description = models.TextField(
        help_text='Full description. Supports MarkDown')

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return urls.reverse('contests:contest', args=[self.id])

    def is_user_participating(self, user):
        if self.participation_mode == ContestParticipationMode.Individual:
            return self.participants.filter(
                individualparticipant__user=user).exists()
        elif self.participation_mode == ContestParticipationMode.Team:
            return self.participants.filter(
                teamparticipant__team__members=user).exists()
        else:
            raise ValueError('Unknown participation mode: %s' %
                             (self.participation_mode, ))

    def get_user_team(self, user):
        """
        Return Team object for user if contest is team-based and user is a participant
        Otherwise return None
        """
        if self.participation_mode != ContestParticipationMode.Team:
            return None

        team_participant = self.get_participant_for_user(user)
        if team_participant is None:
            return None

        return team_participant.team

    def get_participant_for_user(self, user):
        """ Returns IndividualParticipant or TeamParticipant """
        participant = None

        if user.is_anonymous:
            return None

        if self.participation_mode == ContestParticipationMode.Team:
            participant = self.participants.filter(
                teamparticipant__team__members=user).first()
        if self.participation_mode == ContestParticipationMode.Individual:
            participant = self.participants.filter(
                individualparticipant__user=user).first()

        return participant

    def can_register_now(self):
        return (self.registration_type in [
            ContestRegistrationType.Open, ContestRegistrationType.Moderated
        ] and self.registration_start_time <= timezone.now() <
                self.registration_finish_time)

    def can_register_in_future(self):
        return (self.registration_type in [
            ContestRegistrationType.Open, ContestRegistrationType.Moderated
        ] and timezone.now() < self.registration_start_time)

    def is_running(self):
        return self.start_time <= timezone.now() < self.finish_time

    def is_finished(self):
        return self.finish_time <= timezone.now()

    def is_started(self):
        return self.start_time <= timezone.now()

    def show_menu_on_top(self):
        return self.is_started()

    def is_team(self):
        return self.participation_mode == ContestParticipationMode.Team

    def is_individual(self):
        return self.participation_mode == ContestParticipationMode.Individual
示例#12
0
class EntranceStatus(models.Model):
    class Status(djchoices.DjangoChoices):
        NOT_PARTICIPATED = djchoices.ChoiceItem(1, 'Не участвовал в конкурсе')
        AUTO_REJECTED = djchoices.ChoiceItem(2, 'Автоматический отказ')
        NOT_ENROLLED = djchoices.ChoiceItem(3, 'Не прошёл по конкурсу')
        ENROLLED = djchoices.ChoiceItem(4, 'Поступил')
        PARTICIPATING = djchoices.ChoiceItem(5, 'Подал заявку')
        IN_RESERVE_LIST = djchoices.ChoiceItem(6, 'В резервном списке')

    school = models.ForeignKey(
        'schools.School',
        on_delete=models.CASCADE,
        related_name='entrance_statuses',
    )

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='entrance_statuses',
    )

    # created_by=None means system's auto creating
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='+',
        blank=True,
        null=True,
        default=None,
    )

    public_comment = models.TextField(
        help_text='Публичный комментарий. Может быть виден поступающему',
        blank=True,
    )

    private_comment = models.TextField(
        help_text='Приватный комментарий. Виден только админам вступительной',
        blank=True,
    )

    is_status_visible = models.BooleanField(default=False)

    status = models.IntegerField(choices=Status.choices,
                                 validators=[Status.validator])

    created_at = models.DateTimeField(auto_now_add=True)

    updated_at = models.DateTimeField(auto_now=True)

    is_approved = models.BooleanField(
        help_text=
        'Подтверждено ли участие пользователем. Имеет смысл, только если статус = «Поступил»',
        default=False)

    approved_at = models.DateTimeField(null=True, blank=True, default=None)

    @property
    def is_enrolled(self):
        return self.status == self.Status.ENROLLED

    @property
    def is_in_reserve_list(self):
        return self.status == self.Status.IN_RESERVE_LIST

    def approve(self):
        self.is_approved = True
        self.approved_at = django.utils.timezone.now()
        self.save()

    def remove_approving(self):
        self.is_approved = False
        self.approved_at = None
        self.save()

    @classmethod
    def create_or_update(cls, school, user, status, **kwargs):
        with transaction.atomic():
            current = cls.objects.filter(school=school, user=user).first()
            if current is None:
                current = cls(school=school,
                              user=user,
                              status=status,
                              **kwargs)
            else:
                current.status = status
                for key, value in current:
                    setattr(current, key, value)
            current.save()

    @classmethod
    def get_visible_status(cls, school, user):
        return cls.objects.filter(school=school,
                                  user=user,
                                  is_status_visible=True).first()

    def __str__(self):
        return '%s %s' % (self.user, self.Status.values[self.status])

    class Meta:
        verbose_name_plural = 'User entrance statuses'
        unique_together = ('school', 'user')