Cómo comparar fechas en Django

Me gustaría comparar una fecha con la fecha actual en Django, preferiblemente en la plantilla, pero también es posible hacerlo antes de renderizar la plantilla. Si la fecha ya pasó, quiero decir “En el pasado”, mientras que si es en el futuro, quiero dar la fecha.

Esperaba que uno pudiera hacer algo como esto:

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

Con la fecha actual de hoy, pero esto no funciona. No pude encontrar nada de esto en los documentos de Django. ¿Alguien puede dar algún consejo?

Compare la fecha en la vista y pase algo como in_the_past (boolean) al extra_context.

O mejor agregarlo al modelo como una propiedad.

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

Luego en la vista:

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

Básicamente, la plantilla no es el lugar para la comparación de fechas de IMO.

A partir de Django 1.8, la siguiente construcción ligeramente desagradable hace el trabajo:

 {% now "Ymd" as todays_date %} {% if todays_date < someday|date:"Ymd" %} 

It's not too late!

{% endif %}

Hackish, pero evita la necesidad de una etiqueta personalizada o procesador de contexto.

Agregué date_now a mi lista de procesadores de contexto.

Así que en la plantilla hay una variable llamada “date_now” que es solo datetime.datetime.now ()

Haga un procesador de contexto llamado date_now en el archivo context_processors.py

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

Y en settings.py, modifique CONTEXT_PROCESSORS para incluirlo, en mi caso es

 app_name.context_processors.date_now 

Siempre puede pasar datetime.datetime.now (ya que los modelos de django usan el objeto de fecha y hora estándar de Python).

Usando render_to_response, podría hacer algo como esto (después de importar datetime):

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

Ahora que tiene acceso a “ahora” dentro de la plantilla, puede comparar fechas tal como lo hizo en sus ejemplos.

Además, si usa RequestContext en sus vistas, podrá agregar “ahora” como un procesador de contexto si lo necesita en varios archivos. Esto agregará “ahora” a cualquier plantilla representada con un RequestContext.

Sin embargo, es más realista que simplemente obtenga la lista de registros que están antes en su consulta original y evite consultar datos inútiles en primer lugar:

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

Además de la respuesta beneficiosa de @ bx2, si su campo es un campo datetime, simplemente llame a la función date () para modelar el campo datetime:

 from datetime import date @property def is_past_due(self): if date.today() > self.date.date(): return True return False 

Encontré esta pregunta y tuve un problema similar. Estaba buscando mostrar información si solo había ocurrido en el pasado.

Usando la etiqueta “timesince” de Django en la plantilla, pude resolver mi problema. No estoy diciendo que sea eficiente, pero funciona para mí.

En plantilla:

 {% if model_name.date_time|timesince >= "1 min" %} 

In the past

{% else %}

{{ model_name.date_time }}

{% endif %}

Creo que la forma más fácil de lograr esto es importando datetime en su views.py y pasando la fecha de hoy como datos de contexto.

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

Luego, en las tags de la plantilla, podrías hacer algo como esto.

  {% if listing.date < today % } 

De esta manera, si está pasando una lista de objetos como contexto, puede aplicar el filtro a cada línea a medida que la imprime en la plantilla HTML. Tenía una lista de elementos que había filtrado y estaba usando Bootstrap para estilizar mientras los mostraba. Quería destacar las fechas de vencimiento y aplicar el filtro solo si una de mis fechas era inferior a la fecha de hoy.