it-swarm.com.de

Wie kann ich ein Datum eines DateTimeField in Django filtern?

Ich versuche, eine DateTimeField zu filtern, die mit einem Datum verglichen wird. Ich meine:

MyObject.objects.filter(datetime_attr=datetime.date(2009,8,22))

Ich bekomme eine leere Abfrage-Liste als Antwort, weil (ich denke) ich nicht über die Zeit nachdenke, aber ich möchte "jederzeit".

Gibt es in Django einen einfachen Weg, dies zu tun?

Ich habe die Uhrzeit in der datetime eingestellt, es ist kein 00:00.

147
Xidobix

Solche Lookups werden in Django.views.generic.date_based wie folgt implementiert:

{'date_time_field__range': (datetime.datetime.combine(date, datetime.time.min),
                            datetime.datetime.combine(date, datetime.time.max))} 

Da es ziemlich ausführlich ist, gibt es Pläne, die Syntax mit dem __date-Operator zu verbessern. Überprüfen Sie " # 9596 Ein DateTimeField mit einem Datum zu vergleichen ist zu hart ", um weitere Informationen zu erhalten.

105
Piotr Czapla
YourModel.objects.filter(datetime_published__year='2008', 
                         datetime_published__month='03', 
                         datetime_published__day='27')

// nach Kommentaren bearbeiten

YourModel.objects.filter(datetime_published=datetime(2008, 03, 27))

funktioniert nicht, da ein datetime-Objekt mit Zeitwerten von 0 erstellt wird, sodass die Zeit in der Datenbank nicht übereinstimmt.

89
zalew

Hier sind die Ergebnisse, die ich mit der Timeit-Funktion von ipython erhielt:

from datetime import date
today = date.today()

timeit[Model.objects.filter(date_created__year=today.year, date_created__month=today.month, date_created__day=today.day)]
1000 loops, best of 3: 652 us per loop

timeit[Model.objects.filter(date_created__gte=today)]
1000 loops, best of 3: 631 us per loop

timeit[Model.objects.filter(date_created__startswith=today)]
1000 loops, best of 3: 541 us per loop

timeit[Model.objects.filter(date_created__contains=today)]
1000 loops, best of 3: 536 us per loop

enthält scheint schneller zu sein.

74
Moreno
Mymodel.objects.filter(date_time_field__contains=datetime.date(1986, 7, 28))

das obige ist was ich verwendet habe. Es funktioniert nicht nur, es hat auch einen logischen Hintergrund.

35
kettlehell

Jetzt hat Django den Filter " __date queryset", um Datetime-Objekte nach Datum in der Entwicklungsversion abzufragen. Daher wird es in Kürze in 1.9 verfügbar sein.

35
omat

Dies führt zu den gleichen Ergebnissen wie die Verwendung von __year, __month und __day und scheint für mich zu funktionieren:

YourModel.objects.filter(your_datetime_field__startswith=datetime.date(2009,8,22))
24
mhost

Ab Django 1.9 können Sie dies mit Hilfe von __date für ein datetime-Objekt tun.

Zum Beispiel: MyObject.objects.filter(datetime_attr__date=datetime.date(2009,8,22))

21
Andrew B.

angenommen, active_on ist ein Datumsobjekt, erhöht es um 1 Tag und dann den Bereich 

next_day = active_on + datetime.timedelta(1)
queryset = queryset.filter(date_created__range=(active_on, next_day) )
7
davidj411

Hier ist eine interessante Technik - ich habe die mit Django auf MySQL implementierte Prozedur startswith genutzt, um das Ergebnis zu erreichen, dass nur eine Datums-Uhrzeit nur durch das Datum gesucht wird. Grundsätzlich muss Django bei der Suche in der Datenbank eine String-Konvertierung für das DATETIME MySQL-Speicherobjekt durchführen, sodass Sie darauf filtern und den Zeitstempel-Teil des Datums weglassen können. Auf diese Weise entspricht% LIKE% nur dem Datum Objekt und Sie erhalten jeden Zeitstempel für das angegebene Datum. 

datetime_filter = datetime(2009, 8, 22) 
MyObject.objects.filter(datetime_attr__startswith=datetime_filter.date())

Dadurch wird die folgende Abfrage ausgeführt:

SELECT (values) FROM myapp_my_object \ 
WHERE myapp_my_object.datetime_attr LIKE BINARY 2009-08-22%

Das LIKE BINARY entspricht in diesem Fall dem Datum und dem Zeitstempel. Einschließlich Werte wie:

+---------------------+
| datetime_attr       |
+---------------------+
| 2009-08-22 11:05:08 |
+---------------------+

Hoffentlich hilft das allen, bis Django eine Lösung herausbringt!

2
bbengfort

Hm .. Meine Lösung funktioniert:

Mymodel.objects.filter(date_time_field__startswith=datetime.datetime(1986, 7, 28))
1
satels

Es gibt einen fantastischen Blogpost, der das hier behandelt: Daten und Daten im Django-ORM vergleichen

Die beste Lösung für Django> 1.7, <1.9 ist das Registrieren einer Transformation:

from Django.db import models

class MySQLDatetimeDate(models.Transform):
    """
    This implements a custom SQL lookup when using `__date` with datetimes.
    To enable filtering on datetimes that fall on a given date, import
    this transform and register it with the DateTimeField.
    """
    lookup_name = 'date'

    def as_sql(self, compiler, connection):
        lhs, params = compiler.compile(self.lhs)
        return 'DATE({})'.format(lhs), params

    @property
    def output_field(self):
        return models.DateField()

Dann können Sie es wie folgt in Ihren Filtern verwenden:

Foo.objects.filter(created_on__date=date)

EDIT

Diese Lösung ist definitiv vom Backend abhängig. Aus dem Artikel:

Natürlich hängt diese Implementierung von Ihrer speziellen SQL-Variante ab, die eine DATE () - Funktion hat. MySQL tut es. SQLite auch. Auf der anderen Seite habe ich nicht persönlich mit PostgreSQL gearbeitet, aber einige Googles lassen mich glauben, dass es keine DATE () - Funktion gibt. Eine so einfache Implementierung scheint daher notwendigerweise etwas vom Backend abhängig zu sein.

0
Dan Gayle

Siehe den Artikel Django-Dokumentation

Es ist der JZ-Antwort sehr ähnlich

ur_data_model.objects.filter(ur_date_field=datetime(2005, 7, 27)
0
shahjapan

In Django 1.7.6 arbeitet:

MyObject.objects.filter(datetime_attr__startswith=datetime.date(2009,8,22))
0
FACode
Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30)
0
Skylar Saveland