Order Django QuerySet for month / day?

I have a list of people, each of whom has a date of birth, which is expected to be stored in DateField. I am trying to create a list of those people sorted by month and day of birth (not counting the year) to display the "birthday".

It seems I can not order QuerySetvalue datetime.month. Is there a way in which this could be done without resorting to coercion to list()?

Thanks in advance, and please let me know if the question needs clarification.

+5
source share
4 answers

QuerySet.extra() :

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

django> = 1.10

django>=1.10, . Extract , order_by QuerySet .

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').all()

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

, 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')
+1

Newer versions of django have a search on DateFields and DateTimeFields. https://docs.djangoproject.com/en/1.11/ref/models/database-functions/#extract

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

0
source

Source: https://habr.com/ru/post/1776034/


All Articles