コード例 #1
0
class Answer(TreeNode):
    objects: AnswerQuerySet = AnswerQuerySet.as_manager()

    created = models.DateTimeField(auto_now_add=True, db_index=True)
    modified = models.DateTimeField(null=True, blank=True, db_index=True)

    slug = models.UUIDField(db_index=True, unique=True, default=uuid.uuid4)
    question = models.ForeignKey('homework.Question', on_delete=models.CASCADE)
    author = models.ForeignKey('users.User', on_delete=models.CASCADE)

    text = MarkdownxField()

    class Meta:
        verbose_name = _('Homework answer')
        verbose_name_plural = _('Homework answers')
        ordering = ['created']
        permissions = [
            ('see_all_answers', _('May see answers from every user')),
        ]

    def save(self, *args, **kwargs):
        if self.pk:
            self.modified = timezone.now()

        return super().save(*args, **kwargs)
コード例 #2
0
class Answer(TreeNode):
    objects: AnswerQuerySet = AnswerQuerySet.as_manager()

    created = models.DateTimeField(auto_now_add=True, db_index=True)
    modified = models.DateTimeField(auto_now=True, db_index=True)

    slug = models.UUIDField(db_index=True, unique=True, default=uuid.uuid4)
    question = models.ForeignKey('homework.Question', on_delete=models.CASCADE)
    author = models.ForeignKey('users.User', on_delete=models.CASCADE)
    do_not_crosscheck = models.BooleanField(_('Exclude from cross-checking'),
                                            default=False)

    text = MarkdownxField()

    class Meta:
        verbose_name = _('Homework answer')
        verbose_name_plural = _('Homework answers')
        ordering = ['created']
        permissions = [
            ('see_all_answers', _('May see answers from every user')),
        ]

    def get_root_answer(self):
        ancesorts = self.ancestors()
        if ancesorts.count():
            return ancesorts[0]

        return self

    def get_absolute_url(self):
        root = self.get_root_answer()

        url = urljoin(settings.FRONTEND_URL, f'homework/answers/{root.slug}/')

        if root != self:
            url = f'{url}#{self.slug}'  # append hash with current answer id

        return url

    def get_purchased_course(self):
        latest_purchase = Order.objects.paid().filter(
            user=self.author,
            course__in=self.question.courses.all()).order_by('-paid').first()

        if latest_purchase:
            return latest_purchase.course

    def get_first_level_descendants(self):
        return self.descendants().filter(parent=self.id)

    def __str__(self):
        LENGTH = 30
        text = self.text[:LENGTH]
        if len(text) == LENGTH:
            text += '...'

        return text
コード例 #3
0
class AnswerAccessLogEntry(TimestampedModel):
    objects: AnswerAccessLogEntryQuerySet = AnswerAccessLogEntryQuerySet.as_manager()

    answer = models.ForeignKey('homework.Answer', on_delete=models.CASCADE)
    user = models.ForeignKey('users.User', on_delete=models.CASCADE)

    class Meta:
        indexes = [
            Index(fields=['answer', 'user']),
        ]
        constraints = [
            UniqueConstraint(fields=['answer', 'user'], name='unique_user_and_answer'),
        ]
コード例 #4
0
class AnswerCrossCheck(TimestampedModel):
    answer = models.ForeignKey('homework.Answer', on_delete=models.CASCADE)
    checker = models.ForeignKey('users.User', on_delete=models.CASCADE)

    class Meta:
        indexes = [
            Index(fields=['answer', 'checker']),
        ]

        constraints = [
            UniqueConstraint(fields=['answer', 'checker'],
                             name='unique_checker_and_answer'),
        ]
コード例 #5
0
class AnswerCrossCheck(TimestampedModel):
    answer = models.ForeignKey('homework.Answer', on_delete=models.CASCADE)
    checker = models.ForeignKey('users.User', on_delete=models.CASCADE)

    class Meta:
        indexes = [
            Index(fields=['answer', 'checker']),
        ]

        constraints = [
            UniqueConstraint(fields=['answer', 'checker'], name='unique_checker_and_answer'),
        ]

    def is_checked(self):
        return self.answer.descendants().filter(author=self.checker).exists()
コード例 #6
0
ファイル: models.py プロジェクト: f213/education-backend
class Study(TimestampedModel):
    student = models.ForeignKey('users.User', on_delete=models.CASCADE)
    course = models.ForeignKey('products.Course', on_delete=models.CASCADE)
    order = models.OneToOneField('orders.Order', on_delete=models.CASCADE)

    class Meta:
        indexes = [
            Index(fields=['student', 'course']),
        ]
        constraints = [
            UniqueConstraint(fields=['student', 'course'],
                             name='unique_student_course_study'),
        ]

    def __str__(self):
        return f'{self.student} / {self.course}'
コード例 #7
0
ファイル: models.py プロジェクト: fffffrolov/django_demo
class Employee(Timestamped, AppModel):
    branch = models.ForeignKey(
        to='branches.Branch',
        related_name='employees',
        on_delete=models.SET_NULL,
        null=True, blank=True,
    )
    first_name = models.CharField(
        max_length=255,
        db_index=True,
    )
    last_name = models.CharField(
        max_length=255,
        db_index=True,
    )
    position = models.CharField(
        max_length=255,
        db_index=True,
    )

    objects = EmployeeQuerySet.as_manager()

    class Meta:
        ordering = ['-id']
        indexes = [
            GinIndex(name='employee_fname_gin_index', fields=['first_name'], opclasses=['gin_trgm_ops']),
            GinIndex(name='employee_lname_gin_index', fields=['last_name'], opclasses=['gin_trgm_ops']),
        ]

    @property
    def name(self) -> str:
        return ' '.join([name for name in [self.first_name, self.last_name] if name])
コード例 #8
0
ファイル: models.py プロジェクト: iNerV/education-backend
class Record(Shippable):
    course = models.ForeignKey(Course, on_delete=models.CASCADE)

    s3_object_id = models.CharField(max_length=512)
    template_id = models.CharField(
        _('Postmark template_id'),
        max_length=256,
        blank=True,
        null=True,
        help_text=_('Leave it blank for the default template'))

    class Meta:
        ordering = ['-id']
        verbose_name = _('Record')
        verbose_name_plural = _('Records')

    @property
    def name_genitive(self):
        return self.course.name_genitive

    def get_url(self, expires: int = 30 * 24 * 60 * 60):
        return AppS3().get_presigned_url(self.s3_object_id, expires=expires)

    def __str__(self):
        return f'Запись {self.name_genitive}'

    def get_absolute_url(self):
        return self.course.get_absolute_url()
コード例 #9
0
class Diploma(TimestampedModel):
    class Languages(models.TextChoices):
        RU = 'RU', _('Russian')
        EN = 'EN', _('English')

    objects: DiplomaQuerySet = DiplomaQuerySet.as_manager()

    study = models.ForeignKey('studying.Study', on_delete=models.CASCADE)
    slug = models.CharField(max_length=32,
                            db_index=True,
                            unique=True,
                            default=shortuuid.uuid)
    language = models.CharField(max_length=3,
                                choices=Languages.choices,
                                db_index=True)
    image = models.ImageField(upload_to=RandomFileName('diplomas'))

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['study', 'language'],
                                    name='unique_study'),
        ]
        indexes = [
            models.Index(fields=['study', 'language']),
        ]
        ordering = ['-id']
        permissions = [
            ('access_all_diplomas', _('May access diplomas of all students')),
        ]

        verbose_name = _('Diploma')
        verbose_name_plural = _('Diplomas')

    def get_other_languages(self) -> DiplomaQuerySet:
        return self.__class__.objects.filter(study=self.study).exclude(
            pk=self.pk)

    def get_absolute_url(self) -> str:
        return urljoin(settings.DIPLOMA_FRONTEND_URL, f'/{self.slug}/')

    def send_to_student(self):
        send_mail.delay(
            to=self.study.student.email,
            template_id='new-diploma',
            ctx=dict(
                course_name=self.study.course.full_name,
                diploma_url=self.get_absolute_url(),
            ),
            disable_antispam=True,
        )
コード例 #10
0
ファイル: base.py プロジェクト: f213/education-backend
class Shippable(TimestampedModel):
    """Add this to every shippable item"""
    name = models.CharField(max_length=255)
    name_receipt = models.CharField(_('Name for receipts'), max_length=255, help_text='«посещение мастер-класса по TDD» или «Доступ к записи курсов кройки и шитья»')
    full_name = models.CharField(
        _('Full name for letters'), max_length=255,
        help_text='Билет на мастер-класс о TDD или «запись курсов кройки и шитья»',
    )
    slug = models.SlugField()

    price = models.DecimalField(max_digits=8, decimal_places=2)
    old_price = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)

    tinkoff_credit_promo_code = models.CharField(_('Fixed promo code for tinkoff credit'), max_length=64, blank=True, help_text=_('Used in tinkoff credit only'))

    group = models.ForeignKey('products.Group', verbose_name=_('Analytical group'), null=True, blank=True, on_delete=models.SET_NULL)

    class Meta:
        abstract = True

    def get_price_display(self):
        return format_price(self.price)

    def get_old_price_display(self):
        return format_price(self.old_price)

    def get_formatted_price_display(self):
        return format_old_price(self.old_price, self.price)

    def ship(self, to: User, order: Optional[Order] = None):
        return ShipmentFactory.ship(self, to=to, order=order)

    def unship(self, order: Order):
        return ShipmentFactory.unship(order=order)

    def get_price(self, promocode=None) -> Decimal:
        promocode = apps.get_model('orders.PromoCode').objects.get_or_nothing(name=promocode)

        if promocode is not None:
            return promocode.apply(self)

        return self.price

    def get_template_id(self):
        """Get custom per-item template_id"""
        if not hasattr(self, 'template_id'):
            return

        if self.template_id is not None and len(self.template_id):
            return self.template_id
コード例 #11
0
ファイル: models.py プロジェクト: sevdimali/education-backend
class PasswordlessAuthToken(TimestampedModel):
    objects = PasswordlessAuthTokenQuerySet.as_manager()

    user = models.ForeignKey('users.User', on_delete=models.CASCADE)
    token = models.UUIDField(default=uuid.uuid4, unique=True, db_index=True)
    expires = models.DateTimeField(default=default_expiration)
    used = models.DateTimeField(null=True)

    def get_absolute_url(self):
        return urljoin(settings.FRONTEND_URL,
                       '/'.join(['auth', 'passwordless',
                                 str(self.token), '']))

    def mark_as_used(self):
        if not settings.DANGEROUSLY_MAKE_ONE_TIME_PASSWORDLESS_TOKEN_MULTI_PASS:
            self.used = timezone.now()
            self.save()
コード例 #12
0
class Migration(migrations.Migration):

    dependencies = [
        ('models', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Interface',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('local_interface', models.CharField(default=b'',
                                                     max_length=30)),
                ('remote_interface',
                 models.CharField(default=b'', max_length=30, null=True)),
                ('status',
                 models.CharField(choices=[
                     (app.models.models.Status(b'Down'), b'Down'),
                     (app.models.models.Status(b'Shutdown'), b'Shutdown'),
                     (app.models.models.Status(b'Up'), b'Up')
                 ],
                                  default=app.models.models.Status(b'Down'),
                                  max_length=50)),
                ('connected_interface',
                 models.CharField(default=b'', max_length=30)),
                ('connected_router',
                 models.CharField(default=b'', max_length=30)),
                ('card',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   related_name='card',
                                   to='models.Card')),
            ],
        ),
    ]
コード例 #13
0
ファイル: models.py プロジェクト: warderus/education-backend
class Token(TimestampedModel):

    objects = TokenQuerySet.as_manager()  # type: TokenQuerySet

    token = models.CharField(max_length=36,
                             default=uuid.uuid4,
                             unique=True,
                             db_index=True)
    record = models.ForeignKey('courses.Record', on_delete=models.CASCADE)
    expires = models.DateTimeField(blank=True, null=True)

    class Meta:
        verbose_name = _('Onetime token')
        verbose_name_plural = _('Onetime tokens')

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

    def download(self):
        self.expires = timezone.now() + EXPIRATION_TIME
        self.save()

        return self.record.get_url()
コード例 #14
0
ファイル: models.py プロジェクト: kazqvaizer/concrete-maker
class Batch(TimestampedModel):
    recipe = models.ForeignKey("lab.recipe",
                               verbose_name=_("Recipe"),
                               on_delete=models.PROTECT)
    volume = models.DecimalField(_("Volume, m3"),
                                 max_digits=10,
                                 decimal_places=3,
                                 default=0)

    cement_weight = models.DecimalField(_("Cement, kg"),
                                        max_digits=10,
                                        decimal_places=3,
                                        default=0)
    sand_weight = models.DecimalField(_("Sand, kg"),
                                      max_digits=10,
                                      decimal_places=3,
                                      default=0)
    gravel_weight = models.DecimalField(_("Gravel, kg"),
                                        max_digits=10,
                                        decimal_places=3,
                                        default=0)
    water_weight = models.DecimalField(_("Water, kg"),
                                       max_digits=10,
                                       decimal_places=3,
                                       default=0)
    admixture_weight = models.DecimalField(_("Admixture, kg"),
                                           max_digits=10,
                                           decimal_places=3,
                                           default=0)

    class Meta:
        verbose_name = _("Batch")
        verbose_name_plural = _("Batches")

    def __str__(self):
        return f"{self.recipe.name}: {self.volume} м3"
コード例 #15
0
class Order(TimestampedModel):
    objects = OrderQuerySet.as_manager()  # type: OrderQuerySet

    user = models.ForeignKey('users.User', on_delete=models.PROTECT)
    price = models.DecimalField(max_digits=9, decimal_places=2)
    promocode = models.ForeignKey('orders.PromoCode',
                                  verbose_name=_('Promo Code'),
                                  blank=True,
                                  null=True,
                                  on_delete=models.PROTECT)

    paid = models.DateTimeField(
        _('Date when order got paid'),
        null=True,
        blank=True,
        help_text=_('If set during creation, order automaticaly gets shipped'),
    )
    shipped = models.DateTimeField(_('Date when order was shipped'),
                                   null=True,
                                   blank=True)

    course = ItemField('courses.Course',
                       null=True,
                       blank=True,
                       on_delete=models.PROTECT)
    record = ItemField('courses.Record',
                       null=True,
                       blank=True,
                       on_delete=models.PROTECT)
    bundle = ItemField('courses.Bundle',
                       null=True,
                       blank=True,
                       on_delete=models.PROTECT)

    class Meta:
        ordering = ['-id']
        verbose_name = _('Order')
        verbose_name_plural = _('Orders')

    def __str__(self):
        return f'Order #{self.pk}'

    @property
    def item(self):
        """Find the attached item. Simple replacement for ContentType framework
        """
        for field in self.__class__._meta.get_fields():
            if getattr(field, '_is_item', False):
                if getattr(self, f'{field.name}_id', None) is not None:
                    return getattr(self, field.name)

    @classmethod
    def _iterate_items(cls) -> Iterable[models.fields.Field]:
        for field in cls._meta.get_fields():
            if getattr(field, '_is_item', False):
                yield field

    @classmethod
    def get_item_foreignkey(cls, item) -> Optional[models.fields.Field]:
        """
        Given an item model, returns the ForeignKey to it"""
        for field in cls._iterate_items():
            if field.related_model == item.__class__:
                return field.name

    def reset_items(self):
        for field in self._iterate_items():
            setattr(self, field.name, None)

    def set_item(self, item):
        foreign_key = self.__class__.get_item_foreignkey(item)
        if foreign_key is not None:
            self.reset_items()
            setattr(self, foreign_key, item)
            return

        raise UnknownItemException('There is not foreignKey for {}'.format(
            item.__class__))

    def set_paid(self):
        is_already_paid = self.paid is not None

        self.paid = timezone.now()

        self.save()

        if not is_already_paid and self.item is not None:
            self.ship()

    def ship(self):
        """Ship the order. Better call it asynchronously"""
        self.item.ship(to=self.user)

        self.shipped = timezone.now()

        self.save()

        order_got_shipped.send(
            sender=self.__class__,
            order=self,
        )
コード例 #16
0
class LeadCampaignLogEntry(TimestampedModel):
    campaign = models.ForeignKey(EmailLeadMagnetCampaign, on_delete=models.CASCADE)
    user = models.ForeignKey('users.User', on_delete=models.CASCADE)
コード例 #17
0
ファイル: order.py プロジェクト: yakimka/education-backend
class Order(TimestampedModel):
    objects = OrderQuerySet.as_manager()  # type: OrderQuerySet

    user = models.ForeignKey('users.User',
                             verbose_name=_('User'),
                             on_delete=models.PROTECT)
    price = models.DecimalField(_('Price'), max_digits=9, decimal_places=2)
    promocode = models.ForeignKey('orders.PromoCode',
                                  verbose_name=_('Promo Code'),
                                  blank=True,
                                  null=True,
                                  on_delete=models.PROTECT)

    paid = models.DateTimeField(
        _('Date when order got paid'),
        null=True,
        blank=True,
        help_text=_('If set during creation, order automaticaly gets shipped'),
    )
    shipped = models.DateTimeField(_('Date when order was shipped'),
                                   null=True,
                                   blank=True)

    desired_bank = models.CharField(_('User-requested bank string'),
                                    blank=True,
                                    max_length=32)

    course = ItemField(to='products.Course',
                       verbose_name=_('Course'),
                       null=True,
                       blank=True,
                       on_delete=models.PROTECT)
    record = ItemField(to='products.Record',
                       verbose_name=_('Record'),
                       null=True,
                       blank=True,
                       on_delete=models.PROTECT)
    bundle = ItemField(to='products.Bundle',
                       verbose_name=_('Bundle'),
                       null=True,
                       blank=True,
                       on_delete=models.PROTECT)

    giver = models.ForeignKey('users.User',
                              verbose_name=_('Giver'),
                              null=True,
                              blank=True,
                              on_delete=models.SET_NULL,
                              related_name='created_gifts')
    desired_shipment_date = models.DateTimeField(
        _('Date when the gift should be shipped'), null=True, blank=True)
    gift_message = models.TextField(_('Gift message'), default='', blank=True)
    notification_to_giver_is_sent = models.BooleanField(default=False)

    class Meta:
        ordering = ['-id']
        verbose_name = _('Order')
        verbose_name_plural = _('Orders')

    def __str__(self):
        return f'Order #{self.pk}'

    @property
    def item(self):
        """Find the attached item. Simple replacement for ContentType framework
        """
        for field in self.__class__._meta.get_fields():
            if getattr(field, '_is_item', False):
                if getattr(self, f'{field.name}_id', None) is not None:
                    return getattr(self, field.name)

    @classmethod
    def _iterate_items(cls) -> Iterable[models.fields.Field]:
        for field in cls._meta.get_fields():
            if getattr(field, '_is_item', False):
                yield field

    @classmethod
    def get_item_foreignkey(cls, item) -> Optional[models.fields.Field]:
        """
        Given an item model, returns the ForeignKey to it"""
        for field in cls._iterate_items():
            if field.related_model == item.__class__:
                return field.name

    def reset_items(self):
        for field in self._iterate_items():
            setattr(self, field.name, None)

    def set_item(self, item):
        foreign_key = self.__class__.get_item_foreignkey(item)
        if foreign_key is not None:
            self.reset_items()
            setattr(self, foreign_key, item)
            return

        raise UnknownItemException('There is not foreignKey for {}'.format(
            item.__class__))

    def set_paid(self, silent=False):
        from orders.services.order_is_paid_setter import Griphook
        Griphook(self, silent=silent)()

    def ship(self, silent: bool = False):
        """Ship the order. Better call it asynchronously"""
        from orders.services.order_shipper import Pigwidgeon
        Pigwidgeon(self, silent=silent)()