Cómo crear un filtro de conjunto de consultas Django comparando dos campos de fecha en el mismo modelo

82

Intento obtener una consulta en la que el registro de actividad está obsoleto en mi índice de Solr. Quiero verificar si la Activity.updatedfecha en la base de datos es mayor que la Activity.added_toSolr_datedel mismo registro.

stale_activities_queryset = Activity.objects.filter(updated__gte = self.added_toSolr_date) 

Modelo

class Activity(models.Model):
    # Last time entry / metric was updated in the Activity model database
    updated =  models.DateTimeField( verbose_name="CRUD date")
    # When it was added to Solr Index Date
    added_toSolr_date = models.DateTimeField(blank=True, null=True, verbose_name="Added to Solr Index Date")

Hice referencia a los documentos de Django Query: https://docs.djangoproject.com/en/1.4/ref/models/querysets/ Y pruebas unitarias para muestras: https://github.com/django/django/blob/master/tests/ modeltests / or_lookups / tests.py

También buscado aquí en Stackoverflow. Todos los ejemplos usan una fecha ingresada en lugar de comparar dos campos de fecha en el mismo modelo.

Carlos Ferreira
fuente

Respuestas:

162

F objetos.

from django.db.models import F
stale_activities = Activity.objects.filter(updated__gte=F('added_toSolr_date')) 
Yuji 'Tomita' Tomita
fuente
¡Muchas gracias! ¿Cómo descubrió esto?
Carlos Ferreira
6
@CarlosFerreira, a través de años de usar django todos los días. Realmente no puedo decir cuándo.
Yuji 'Tomita' Tomita
buena solucion! casi publicó la misma pregunta
Ron
¡Gracias! ¡Yo estaba buscando esto!
Alex Santos
2
Esto parece fallar si una de las fechas es NULL. Usar Q para verificar si hay nulos o comparar y aún falla. Aunque no lo haría en MySQL, ¿alguien más está viendo esto?
Paul Kenjora
3

La solución de Yuji Tomita, desafortunadamente, no funcionó.

Considere un modelo a continuación:

class list(models.Model):
    text = models.CharField(max_length=140)
    created = models.DateTimeField()
    modified = models.DateTimeField()

Conjunto de consultas:

my_list = todolist.objects.order_by('created').filter(created__gte=F('modified'))

Modelo:

{% if my_list %}
{% for list in my_list %}
{{ list.text}}
{% endfor %}
{% else %}
<p>there is no list</p>
{% endif %}

Al final me sale una lista vacía, pero sé que no es correcta. También he usado lo siguiente dentro de la plantilla (sin filtro de conjunto de consultas):

{% if list.created|date:'d m y h:i:s' == list.modified|date:'d m y h:i:s' %}

Funcionó, pero preferiría ver una solución más elegante.

Sergey Krivoy
fuente
En una lectura rápida, parece que está haciendo dos cosas diferentes en su filtro de conjunto de consultas y su código de plantilla. En el primero está usando 'gte' y en el segundo está usando '=='. ¿Es por eso que los dos no producen los mismos resultados? Estoy tratando de averiguar por qué el uso mydate__exact = F('my_other_date')en una consulta no funciona cuando 'my_other_date' es None, yo mismo.
Jenniwren
Tenía otra razón por la que no funcionaría. Usando django-extensions TimeStampedModel, las marcas de tiempo createdy updatedequivalen al milisegundo. Hay un retraso mínimo. Mi solución rápida fue compararlo con el segundo.
tschale