6
votes

Comment puis-je obtenir une valeur "année" distincte d'un modèle Django avec un champ DateTime?

Je peux filtrer avec succès par une année donnée dans mon modèle Django, mais j'ai du mal à trouver un moyen de répertorier des années valides afin qu'un utilisateur puisse y accéder.

J'ai un modèle Django avec une "datetime" définie Champ, oh-so-- à l'origine nommé «date». Dans mes modèles, je peux accéder au champ "bar.date.date.date.year", donc je sais qu'il existe, mais lorsque j'essaie la fonction suivante ... xxx

On m'interris que "" L'objet "intégré_function_or_mesthod" n'a pas d'attribut "année" "

je peux seulement supposer que je" m "m" cropiène sur un aspect de Python Je ne connais pas, mais je ne peux pas Déterminez ce que c'est. Je suis tout à fait certain que cela doit être syntaxique, mais passé cela ...


0 commentaires

7 Réponses :


3
votes

Le premier .date code> accède à un objet DateTime.

Le second .date code> accède à une méthode sur des objets DateTime qui renvoie un objet de date mais ne l'appelle pas ( Cette étape est inutile). P>

La dernière partie (la façon dont vous avez écrites) tente d'accéder à l'attribut code> code> de la méthode de date, au lieu d'accéder à l'année code> attribut du résultat de l'appel de la méthode de date. p>

Correction du code pour voir la différence, il ressemblerait à ceci ... P>

blog_years=[]
for entry in blog_entries:
    if entry.date.year not in blog_years:
        blog_years.append(entry.date.year)


5 commentaires

Je pense que je comprends ce que vous dites - et vous obtenez le chèque de réponse parce que vous avez fait une bien meilleure explication de ce qui se passe. Juste pour vérifier, vous dites que, puisque blog_enterry.date est une référence «DateTime», je n'ai pas besoin de résoudre cela à une référence de date avec .Date (), parce que l'objet DateTime comprend tout aussi bien qu'une date objet fait? (Presque comme l'hérité inverse ... ou plus probablement, la date hérite d'une «année» de DateTime, plutôt que de le faire déclarer localement)


@Ronlugge Fondamentalement, oui. L'objet DateTime n'est qu'un objet de date et un objet de temps combiné. Si vous utilisez la méthode de date () sur celle-ci, vous ne gagnez aucune fonctionnalité supplémentaire, mais perdez les méthodes de temps. Je suggère de lire une partie de Ceci et gardant à l'esprit cette entrée.Date est un objet DateTime pour mieux comprendre.


Merci de votre aide. Je vais certainement dépenser (plus) le temps de lire cette référence cette fois-ci.


Il convient probablement de mentionner que entrée.date.date.year fonctionne dans votre modèle, car le moteur de modèles tentera de l'appeler comme une méthode pour vous, car vous ne pouvez pas utiliser () pour appeler des fonctions modèles.


Vous pouvez simplement utiliser un définir , puis vous n'avez pas besoin de vous soucier de la vérification si l'année est déjà dans la liste.



1
votes

date () est une méthode de DateTime , utilisez xxx


1 commentaires

Merci pour votre explication - que .Date () est une méthode que j'ai à appeler et j'avais besoin de la () dessus, plutôt que d'une propriété que je peux accéder.



0
votes

Ce n'est peut-être pas ce que vous attendez exactement (il peut retourner des années sans messages de blogs): xxx


0 commentaires

5
votes

un python définir ne permet pas des doublons, donc si vous vouliez une liste d'années distinctes:

blog_years = liste (set ([[Entry.date.year pour entrée dans blog_tries]))

ou, vous pouvez utiliser distinct () :

blog_years = blog_tries.distinct (entrée__Date__Year) .Values ​​(entrée__Date__Year)

Bien sûr, ajustez ce qui précède en fonction de votre modèle.


1 commentaires

Pour obtenir la liste doit être utilisé valides_list ('Entry__Date__Year', plat = true)



6
votes

Si vous utilisez Postgres, vous pouvez faire

  BlogEntry.objects.extra(select={"year": "EXTRACT(YEAR  FROM date)"}).distinct().values_list("year", flat=True)


2 commentaires

C'est très performant, comparé à toutes les autres approches qui évaluent les querysets. Mais si vous utilisez .extra (), vous devez garder à l'esprit que l'équipe Django Core envisage de déprécier cette fonction dans le futur .


Au lieu d'être déprécis supplémentaires, vous pouvez utiliser RawSQL Model.Objects .Annotate (année = RawSQL ('extrait (année de la date)', [])) .values_list ('Année', plat = vrai) .Distinct () < / code>



24
votes

Django a un moyen élégant et efficace de le faire. Vous pouvez vérifier de leurs docs https://docs.djangoproject.com/ EN / 3.0 / REF / MODÈLES / QUESYSETS / # DATES Mais pour y passer xxx

Cela fera ressortir des valeurs de l'année distinctes dans la requête.


2 commentaires

Cela devrait être la meilleure réponse.


Valeurs de l'année et non Il renvoie la liste des objets DateTime.Date



1
votes

de django 1.10 Il est devenu très simple xxx


0 commentaires