Ich habe ein Feld in einem Modell wie
class Sample(models.Model):
date = fields.DateField(auto_now=False)
Jetzt muss ich die Objekte nach einem Datenbereich filtern, z. B. alle Objekte, deren Datum zwischen dem 1. Januar 2011 und dem 31. Januar 2011 liegt.
Danke für Ihre Hilfe!
Benutzen
Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])
Oder wenn Sie nur monatlich filtern möchten:
Sample.objects.filter(date__year='2011',
date__month='01')
Wie Bernhard Vallant sagte, wenn Sie ein Abfrageset wünschen, das den specified range ends
ausschließt, sollten Sie seine Lösung betrachten, die gt/lt (größer als/kleiner als) verwendet.
Sie können Djangos filter
mit datetime.date
Objekten verwenden:
import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
sampledate__lte=datetime.date(2011, 1, 31))
Wenn Sie Django-Bereiche mit einem Filter verwenden, stellen Sie sicher, dass Sie den Unterschied zwischen der Verwendung eines Datumsobjekts und eines Datumszeitobjekts kennen. __range ist an Datumsangaben inklusive, aber wenn Sie ein Datumszeitobjekt für das Enddatum verwenden, werden die Einträge für diesen Tag nicht berücksichtigt, wenn die Uhrzeit nicht festgelegt ist.
startdate = date.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
gibt alle Einträge vom Startdatum bis zum Enddatum zurück, einschließlich der Einträge an diesen Daten. Ein schlechtes Beispiel, da dies eine Woche in der Zukunft Einträge zurückgibt, aber Sie bekommen die Drift.
startdate = datetime.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
es fehlen Einträge für 24 Stunden, abhängig davon, wie der Zeitpunkt für die Datumsfelder eingestellt ist.
Sie können die "Unstimmigkeit der Impedanz" umgehen, die durch die ungenaue Genauigkeit des DateTimeField/date
-Objektvergleichs verursacht wird. Dies kann auftreten, wenn Sie range - verwenden, indem Sie einen datetime.timedelta verwenden, um einen Tag mit der letzten Dauer hinzuzufügen Datum im Bereich. Das funktioniert wie:
start = date(2012, 12, 11)
end = date(2012, 12, 18)
new_end = end + datetime.timedelta(days=1)
ExampleModel.objects.filter(some_datetime_field__range=[start, new_end])
Wie bereits erwähnt, werden Datensätze am letzten Tag ignoriert, ohne etwas davon zu tun.
Um die Verwendung von datetime.combine
zu vermeiden, scheint es logischer zu sein, beim Vergleich mit einer DateTimeField
bei Datumsinstanzen zu bleiben, anstatt mit wegwerfenden (und verwirrenden) datetime
-Objekten herumzuspielen. Weitere Erläuterungen finden Sie in den Kommentaren unten.
Ist einfach,
YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())
Funktioniert bei mir
Um es flexibler zu gestalten, können Sie ein FilterBackend wie folgt entwerfen:
class AnalyticsFilterBackend(generic_filters.BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
predicate = request.query_params # or request.data for POST
if predicate.get('from_date', None) is not None and predicate.get('to_date', None) is not None:
queryset = queryset.filter(your_date__range=(predicate['from_date'], predicate['to_date']))
if predicate.get('from_date', None) is not None and predicate.get('to_date', None) is None:
queryset = queryset.filter(your_date__gte=predicate['from_date'])
if predicate.get('to_date', None) is not None and predicate.get('from_date', None) is None:
queryset = queryset.filter(your_date__lte=predicate['to_date'])
return queryset
Noch heute relevant ..__ Sie können auch tun:
import dateutil
import pytz
date = dateutil.parser.parse('02/11/2019').replace(tzinfo=pytz.UTC)