복붙노트

[PYTHON] Django 달 단위로 그룹화 주석 달기

PYTHON

Django 달 단위로 그룹화 주석 달기

나는 아주 기본적인 모델을 가지고있다 :

class Link(models.Model):
    title = models.CharField(max_length=250, null=False)
    user = models.ForeignKey(User)
    url = models.CharField(max_length=250, blank=True, null=True)
    link_count = models.IntegerField(default=0)
    pub_date = models.DateField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

다음을 사용하여 날짜별로 그룹화 된 모든 항목의 목록을 만들 수 있습니다.

Link.objects.values('pub_date').order_by('-pub_date').annotate(dcount=Count('pub_date'))

이것은 당일 자연스럽게 항목을 그룹화합니다. 그러나 실제로하고 싶은 것은 한 달에 한 번씩입니다. 어쨌든 annotate ()를 사용하여이 작업을 수행 할 수 있습니까?

많은 감사합니다,

해결법

  1. ==============================

    1.PostgreSQL을 사용하고 있다면 다음과 같이 동작 할 것입니다 :

    PostgreSQL을 사용하고 있다면 다음과 같이 동작 할 것입니다 :

    from django.db.models import Count
    
    Link.objects.extra(select={'month': 'extract( month from pub_date )'}).values('month').annotate(dcount=Count('pub_date'))
    

    나는 휴대용 추출물이 다른 데이터베이스에 걸쳐 어떻게 있는지 잘 모르겠습니다.

  2. ==============================

    2.

    from django.db import connections
    from django.db.models import Count
    
    Link.objects.extra(select={'month': connections[Link.objects.db].ops.date_trunc_sql('month', 'pub_date')}).values('month').annotate(dcount=Count('pub_date'))
    
  3. ==============================

    3.add ()를 사용하는 대안으로 Django 1.8부터 조건식을 사용할 수도 있습니다.

    add ()를 사용하는 대안으로 Django 1.8부터 조건식을 사용할 수도 있습니다.

    >>> year_overview = Link.objects.filter(pub_date__year=year).aggregate(
        jan=Sum(
            Case(When(created__month=0, then=1),
                 output_field=IntegerField())
        ),
        feb=Sum(
            Case(When(created__month=1, then=1),
                 output_field=IntegerField())
        ),
        mar=Sum(
            Case(When(created__month=2, then=1),
                 output_field=IntegerField())
        ),
        apr=Sum(
            Case(When(created__month=3, then=1),
                 output_field=IntegerField())
        ),
        may=Sum(
            Case(When(created__month=4, then=1),
                 output_field=IntegerField())
        ),
        jun=Sum(
            Case(When(created__month=5, then=1),
                 output_field=IntegerField())
        ),
        jul=Sum(
            Case(When(created__month=6, then=1),
                 output_field=IntegerField())
        ),
        aug=Sum(
            Case(When(created__month=7, then=1),
                 output_field=IntegerField())
        ),
        sep=Sum(
            Case(When(created__month=8, then=1),
                 output_field=IntegerField())
        ),
        oct=Sum(
            Case(When(created__month=9, then=1),
                 output_field=IntegerField())
        ),
        nov=Sum(
            Case(When(created__month=10, then=1),
                 output_field=IntegerField())
        ),
        dec=Sum(
            Case(When(created__month=11, then=1),
                 output_field=IntegerField())
        ),
    )
    
    >>> year_overview
    {'mar': None, 'feb': None, 'aug': None, 'sep': 95, 'apr': 1, 'jun': None, 'jul': None, 'jan': None, 'may': None, 'nov': 87, 'dec': 94, 'oct': 100}
    
  4. ==============================

    4.나는 extra ()가 향후에 사용되지 않을 것이라고 읽었습니다. 대신 Func 객체를 사용하도록 제안합니다. 고통스러운 Case 문을 사용하지 않고 한 달을 추출하는 방법도 있습니다.

    나는 extra ()가 향후에 사용되지 않을 것이라고 읽었습니다. 대신 Func 객체를 사용하도록 제안합니다. 고통스러운 Case 문을 사용하지 않고 한 달을 추출하는 방법도 있습니다.

    from django.db.models.functions import ExtractMonth
    Link.objects.all().annotate(pub_date_month=ExtractMonth('pub_date'))
    
  5. from https://stackoverflow.com/questions/3543379/django-annotate-groupings-by-month by cc-by-sa and MIT license