Заказываете Django QuerySet на месяц / день? - PullRequest
7 голосов
/ 21 ноября 2010

У меня есть список людей, каждый из которых имеет дату рождения, которая, как и ожидалось, хранится в DateField. Я пытаюсь создать список тех людей, отсортированных по месяцу и дню их рождения (без учета года), чтобы иметь вид "у кого скоро день рождения Дисплей.

Не могу заказать QuerySet по значению datetime.month этого человека. Есть ли способ сделать это, не прибегая к принуждению к list()?

Заранее спасибо и, пожалуйста, дайте мне знать, если вопрос требует уточнения.

Ответы [ 4 ]

7 голосов
/ 21 ноября 2010

Вы можете использовать QuerySet.extra(), чтобы определить поле месяца и отсортировать по нему:

SomeModel.objects.extra(select={'birthmonth': 'MONTH(birthdate)'},
    order_by=['birthmonth']) 
4 голосов
/ 04 июля 2018

Для django> = 2.1

Вы можете отсортировать QuerySet, используя имена поиска по месяцам и дням в DateField.

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

Для django> = 1.10

Использовать функцию базы данных Извлечь для создания дополнительных столбцов месяца и дня с помощью метода annotate затем 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')

Для старых версий 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']
    )
    
1 голос
/ 15 апреля 2018

Я тестировал с использованием 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 голос
/ 21 ноября 2017

Более новые версии django имеют поиск по DateFields и DateTimeFields. https://docs.djangoproject.com/en/1.11/ref/models/database-functions/#extract

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

...