按日期时间的月/日订购Django QuerySet?

时间:2010-11-21 03:09:24

标签: django datetime sql-order-by django-queryset

我有一份人员名单,每个人都有一个生日,可以预见存储在DateField。我正在尝试创建一个人员列表 - 按他们出生的排序(无视年份) - 有一种“谁的生日是谁即将到来“显示。

我无法通过此人的QuerySet值来订购datetime.month。有没有办法可以在不必诉诸list()的情况下完成这项工作?

提前致谢,如果问题需要澄清,请告诉我。

5 个答案:

答案 0 :(得分:7)

您可以使用QuerySet.extra()定义月份字段并按其排序:

SomeModel.objects.extra(select={'birthmonth': 'MONTH(birthdate)'},
    order_by=['birthmonth']) 

答案 1 :(得分:4)

  

对于Django> = 2.1

您可以使用DateField上的月份和日期查找名称对QuerySet进行排序。

SomeModel.objects.order_by('birth_date__month', 'birth_date__day')
  

对于Django> = 1.10

使用数据库功能Extract通过annotate方法生成额外的月份和日期列,然后order_by这些列只能按其生日对QuerySet进行排序。< / p>

from django.db.models.functions import Extract

SomeModel.objects.annotate(
    birth_date__month = Extract('birth_date', 'month'),
    birth_date__day = Extract('birth_date', 'day')
).order_by('birth_date__month', 'birth_date__day')
  

对于旧Django版本

对于较旧的django版本,您可以使用QuerySet.extra()进行相同的操作,但是您必须编写针对数据库的查询

  • MySQL

    SomeModel.objects.extra(select={
            'birth_date_month': 'MONTH(birth_date)',
            'birth_date_day': 'DAY(birth_date)'
        },
        order_by=['birth_date_month','birth_date_day']
    )
    
  • PostgreSQL

    SomeModel.objects.extra(select={
            'birth_date_month': 'EXTRACT(MONTH FROM birth_date)',
            'birth_date_day': 'EXTRACT(DAY FROM birth_date)'
        },
        order_by=['birth_date_month','birth_date_day']
    )
    
  • SQlite

    SomeModel.objects.extra(select={
            'birth_date_month': 'strftime("%m", birth_date)',
            'birth_date_day': 'strftime("%d", birth_date)'
        },
        order_by=['birth_date_month','birth_date_day']
    )
    

答案 2 :(得分:1)

较新版本的django具有DateFields和DateTimeFields的查找功能。 https://docs.djangoproject.com/en/1.11/ref/models/database-functions/#extract

MyModel.objects.order_by('birthday__month', 'birthday__day')

答案 3 :(得分:1)

我使用django 1.10.8

进行了测试
from django.db.models.functions import Extract
from your_project.your_app.models import Person


CHOICE_MONTH = (
    (None, '--'),
    (1, 1),
    (2, 2),
    (3, 3),
    (4, 4),
    (5, 5),
    (6, 6),
    (7, 7),
    (8, 8),
    (9, 9),
    (10, 10),
    (11, 11),
    (12, 12),
)

class PersonSearchForm(forms.Form):

    name = forms.CharField(label=u'name', required=False)
    month = forms.ChoiceField(label='month', choices=CHOICE_MONTH, required=False)

    def __init__(self, *args, **kwargs):
        self.corporation = kwargs.pop('corporation', None)
        super(PersonSearchForm, self).__init__(*args, **kwargs)

    def get_result_queryset(self):
        q = Q(corporation=self.corporation)
        if self.is_valid():
            name = self.cleaned_data['name']
            if name:
                q = q & Q(name__icontains=name)
            month = self.cleaned_data['month']
            if month:
                q = q & Q(month=int(month))

        return Person.objects.annotate(month=Extract('birthday', 'month'),
                                       day=Extract('birthday', 'day')).filter(q).order_by('month', 'day')

答案 4 :(得分:0)

Post.objects.all()。order_by('date_posted__minute')。reverse() 其中date_posted是您在Post模型中使用的属性。

帖子只是一个示例模型