проблема написания / понимания Django Custom менеджеров - PullRequest
0 голосов
/ 12 октября 2019

У меня проблемы с пользовательскими менеджерами Django. Это может быть просто, но я не очень хорошо понимаю менеджеров. вот мой код:

class Season(models.Model):
    id       = models.AutoField(auto_created=True, primary_key=True)
    sku      = models.CharField(max_length=16, default=secrets.token_urlsafe(8), editable=False)
    title    = models.CharField(max_length=64, unique=True)
    slug     = models.SlugField(max_length=64, unique=True)
    tutorial = models.ForeignKey(Tutorial, on_delete=models.DO_NOTHING)
    created  = models.DateTimeField(auto_now_add=True)

    objects    = models.Manager() # Default Manager
    custom_obj = SeasonManager()  # Custom Manager in (managers.py)

    def __str__(self):
        return self.title

class Lesson(models.Model):
    id      = models.AutoField(auto_created=True, primary_key=True)
    sku     = models.CharField(max_length=16, default=secrets.token_urlsafe(8), editable=False)
    title   = models.CharField(max_length=64, unique=True)
    slug    = models.SlugField(max_length=64, unique=True)
    content = models.TextField()
    season  = models.ForeignKey(Season, on_delete=models.SET_NULL, null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title


class Video(models.Model):
    id       = models.AutoField(auto_created=True, primary_key=True)
    sku      = models.CharField(max_length=16, default=secrets.token_urlsafe(8), editable=False)
    title    = models.CharField(max_length=64, unique=True)
    slug     = models.SlugField(max_length=64, unique=True)
    content  = models.TextField()
    view     = models.PositiveIntegerField(default=0)
    lesson   = models.ForeignKey(Lesson, on_delete=models.SET_NULL, null=True, blank=True)
    created  = models.DateTimeField(auto_now_add=True)
    video_file   = models.FileField(upload_to='tutorialApp/videos')
    video_length = models.CharField(max_length=32)

    def __str__(self):
        return self.title

Структура следующая: в каждом сезоне есть несколько уроков, в каждом уроке есть несколько видео, а у каждого видео есть продолжительность.

Я хочу написать менеджераэто показывает сумму длин видео в сезон. (менеджер, который показывает, сколько минут видео в сезоне)

И я также не знаю, какой тип поля лучше всего подходит для переменной video_length? На данный момент моя длина видео равна CharField, поэтому, когда я пишу 1:14, это означает, что это 1 час 14 минут. Спасибо.

1 Ответ

0 голосов
/ 12 октября 2019

Во-первых, я настоятельно рекомендую хранить video_length как IntegerField от количества минут, чтобы вам было проще использовать его в арифметике или сравнении.

Во-вторых, я думаю, что выищутся агрегации / аннотации [0], а не менеджеры, и они используются в сочетании с методами модели [1].

Итак, пример того, что вы можете сделать:

class Season(models.Model):
    id       = models.AutoField(auto_created=True, primary_key=True)
    sku      = models.CharField(max_length=16, default=secrets.token_urlsafe(8), editable=False)
    title    = models.CharField(max_length=64, unique=True)
    slug     = models.SlugField(max_length=64, unique=True)
    tutorial = models.ForeignKey(Tutorial, on_delete=models.DO_NOTHING)
    created  = models.DateTimeField(auto_now_add=True)

    objects    = models.Manager()

    def __str__(self):
        return self.title

    def total_video_length(self):
        season_videos = Video.objects.filter(lesson__season=self)
        aggregated = season_videos.aggregate(total_length=models.Sum('video_length'))
        return aggregated['sum']

# So that elsewhere you can do something like:
season = Season.objects.first()
total_video_length = season.total_video_length()

[0] https://docs.djangoproject.com/en/2.2/topics/db/aggregation/

[1] https://docs.djangoproject.com/en/2.2/topics/db/models/#model-methods

...