Як створити фільтр набору запитів Django, порівнюючи два поля дати в одній моделі


82

Спроба отримати запит, де запис активності застарілий в моєму індексі Solr. Я хочу перевірити, чи Activity.updatedне перевищує дата в базі даних дати Activity.added_toSolr_dateдля того самого запису.

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

Модель

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")

Я посилався на документи Django Query: https://docs.djangoproject.com/en/1.4/ref/models/querysets/ І модульні тести для зразків: https://github.com/django/django/blob/master/tests/ modeltests / or_lookups / tests.py

Також шукали тут на Stackoverflow. Усі приклади використовують введену дату замість порівняння двох полів дати в одній моделі.

Відповіді:


162

F об'єкти.

from django.db.models import F
stale_activities = Activity.objects.filter(updated__gte=F('added_toSolr_date')) 

Дуже дякую! Як ви це виявили?
Carlos Ferreira

6
@CarlosFerreira, через роки щоденного використання django. Я не можу точно сказати коли.
Yuji 'Tomita' Tomita

приємне рішення! майже опублікував те саме запитання
Рон

Дякую! Я шукав це!
Alex Santos

2
Здається, це не вдається, якщо одна з дат NULL. Використання Q для перевірки на нуль або порівняння і все ще не вдається. Хоча це не було б у MySQL, хтось ще бачив це?
Paul Kenjora

3

Рішення Yuji Tomita, на жаль, не спрацювало.

Розглянемо модель нижче:

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

Набір запитів:

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

Шаблон:

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

Зрештою я отримую порожній список, але я знаю, це не правильно. Я також використовував наступне всередині шаблону (без фільтру набору запитів):

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

Це спрацювало, але я волів би бачити більш елегантне рішення.


При швидкому прочитанні здається, що ви робите дві різні речі у своєму фільтрі набору запитів та коді нашого шаблону. У першій ви використовуєте 'gte', а в другій - '=='. Це чому ці два результати не дають однакових результатів? Я намагаюся зрозуміти, чому використання mydate__exact = F('my_other_date')в запиті не працює, коли 'my_other_date' має значення None, я сам.
jenniwren

У мене була інша причина, чому це не спрацювало. Використовуючи django-extensions TimeStampedModel, то createdі updatedтимчасові мітки рівні аж до milisecond. Існує мінімальна затримка. Моїм швидким виправленням було просто порівняти це з другим.
tschale
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.