web-dev-qa-db-fra.com

Comment comparer les dates à Django

Je voudrais comparer une date à la date actuelle dans Django, de préférence dans le modèle, mais il est également possible de le faire avant de rendre le modèle. Si la date est déjà passée, je veux dire "dans le passé", tandis que si c'est dans l'avenir, je veux donner la date.

J'espérais pouvoir faire quelque chose comme ça:

{% if listing.date <= now %} 
     In the past 
{% else %} 
     {{ listing.date|date:"d M Y" }} 
{% endif %}

Avec maintenant être la date d'aujourd'hui, mais cela ne fonctionne pas. Je n'ai rien trouvé à ce sujet dans la documentation Django. Quelqu'un peut-il donner des conseils?

40
Herman Schaaf

Comparez la date dans la vue et transmettez quelque chose comme in_the_past (boolean) à extra_context.

Ou mieux l'ajouter au modèle en tant que propriété.

from datetime import date

@property
def is_past_due(self):
    return date.today() > self.date

Puis dans la vue:

{% if listing.is_past_due %}
    In the past
{% else %}
    {{ listing.date|date:"d M Y" }}
{% endif %}

Fondamentalement, le modèle n’est pas l’endroit idéal pour la comparaison des dates, OMI.

87
bx2

A partir de Django 1.8, la construction suivante légèrement désagréable fait le travail:

{% now "Y-m-d" as todays_date %}
{% if todays_date < someday|date:"Y-m-d" %}
   <h1>It's not too late!</h1>
{% endif %}

Hackish, mais il évite le besoin d'une balise personnalisée ou d'un processeur de contexte.

10
Dirk Bergstrom

J'ai ajouté date_now à ma liste de processeurs de contexte.

Donc, dans le modèle, il y a une variable appelée "date_now" qui est simplement datetime.datetime.now ()

Créez un processeur de contexte appelé date_now dans le fichier context_processors.py.

import datetime

def date_now(request):
    return {'date_now':datetime.datetime.now()}

Et dans settings.py, modifiez CONTEXT_PROCESSORS pour l’inclure, dans mon cas c’est

app_name.context_processors.date_now
9
adiktofsugar

Vous pouvez toujours transmettre datetime.datetime.now (car les modèles Django utilisent l'objet datetime standard de Python).

En utilisant render_to_response, vous pouvez faire quelque chose comme ceci (après avoir importé datetime):

return render_to_response('template.html', {'now': datetime.datetime.now()})

Maintenant que vous avez accès à "maintenant" à l'intérieur du modèle, vous pouvez comparer les dates comme vous l'avez fait dans vos exemples.

De plus, si vous utilisez RequestContext dans vos vues, vous pourrez ajouter "maintenant" comme processeur de contexte si vous en avez besoin dans plusieurs fichiers. Cela ajoutera "maintenant" à tout modèle rendu avec un RequestContext.

Cependant, il est plus réaliste que vous obteniez simplement la liste des enregistrements qui se trouvaient auparavant dans votre ensemble de requêtes d'origine et évitiez de rechercher des données inutiles en premier lieu:

listing.objects.filter(date__lt=datetime.datetime.now())
1
monokrome

outre la réponse utile @ bx2, si votre champ est un champ datetime, appelez simplement la fonction date () pour modéliser les champs datetime:

from datetime import date

@property
def is_past_due(self):
    if date.today() > self.date.date():
        return True
    return False
1
Evren Kutar

J'ai trouvé cette question et eu un problème similaire. Je cherchais à afficher des informations si elles ne s’étaient produites que par le passé. 

En utilisant la balise "timesince" de Django dans le modèle, j'ai pu résoudre mon problème. Je ne dis pas que c'est efficace, mais ça marche pour moi. 

Dans le modèle:

{% if model_name.date_time|timesince >= "1 min" %}
   <p>In the past</p>
{% else %}
   <p>{{ model_name.date_time }}</p>
{% endif %}
0
Dustin O

Je pense que le moyen le plus simple d'y parvenir est d'importer de la date et l'heure dans votre view.py et de passer la date d'aujourd'hui en tant que données contextuelles. 

context['today'] = datetime.date.today()

Ensuite, dans les balises de modèle, vous pouvez faire quelque chose comme ceci.

 {% if listing.date < today % }

Ainsi, si vous transmettez une liste d'objets en tant que contexte, vous pouvez appliquer le filtre à chaque ligne lors de son affichage dans le modèle HTML. J'avais une liste d'éléments que j'avais filtrés et j'utilisais Bootstrap pour styliser mon affichage. Je voulais faire ressortir les dates de retard et appliquer le filtrage uniquement si l'une de mes dates était inférieure à la date d'aujourd'hui. 

0
Sherd