7
votes

Commander un requérant Django par un mois / jour de DateTime?

J'ai une liste de personnes, chaque personne ayant une date de naissance, qui est stockée de manière prévisible dans un datefield . J'essaie de créer une liste de ces personnes - triées par le mois et jour de leur naissance (ignorant l'année) - avoir une sorte de "qui est l'anniversaire de qui est l'anniversaire à venir "Affichage.

Je n'arrive pas à commander un QuerySet par la valeur DateTime.Month de la personne . Y a-t-il un moyen que cela puisse être fait sans avoir à recourir à la contrainte à une liste () ?

Merci d'avance et laissez-moi savoir si la question a besoin de clarification.


0 commentaires

5 Réponses :


9
votes

Vous pouvez utiliser queryset.extra () code> pour définir un champ de mois et trier par celui-ci:

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


3 commentaires

Merci pour la réponse rapide! Je voulais juste clarifier pour ceux qui utilisent PostgreSQL pour remplacer mois (daté de naissance) avec extrait (mois à partir de la date de naissance) .


Le nom de la méthode correct est extra


Autant que j'aime cette réponse, il apparaît que la méthode QuerySet.extra () est sur le bloc de découpage et sera éventuellement obsolète. L'État Django Docs, "Utilisez cette méthode en dernier recours" et "c'est une ancienne API que nous visons à se décompresser à un moment donné à l'avenir."



2
votes

Les versions plus récentes de Django ont la recherche sur Datefields et DateTimefields. https://docs.djangoproject.com/fr/1.11 / ref / modèles / fonctions de base de données / extrait

myModel.ObjectS.order_by ('Anniversaire__month', 'Anniversaire__day')


0 commentaires

1
votes

J'ai testé à l'aide de 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 commentaires

S'il vous plaît envisager d'ajouter une explication à votre réponse.



10
votes

pour django> = 2.1 fort> p>

Vous pouvez trier le querySet en utilisant des noms de recherche de mois et de jour sur Datefield. P>

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']
)


0 commentaires

0
votes

post.Object.All (). order_by ('date_posted__minute'). Inverser () où date_posted est votre attribut que vous avez utilisé dans votre modèle de poste.

post est juste un exemple de modèle


1 commentaires

Bonjour Janaki, merci d'avoir posté! Ajout de plus de détails à votre réponse et à l'aide de la terminologie qu'ils utilisent (mois de naissance / jour, plutôt que datte_posted), aidera l'affiche à comprendre votre réponse sans que vous puissiez demander des questions de suivi. Jetez un coup d'œil aux autres réponses à cette question pour avoir une idée de ce qui est nécessaire. Il aide également format de votre code .