J'ai un champ dans un modèle comme
class Sample(models.Model):
date = fields.DateField(auto_now=False)
Maintenant, je dois filtrer les objets en fonction d'une plage de données, par exemple tous les objets dont la date est comprise entre le 1er janvier 2011 et le 31 janvier 2011?
Merci de votre aide!
Utilisation
Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])
Ou si vous essayez simplement de filtrer par mois:
Sample.objects.filter(date__year='2011',
date__month='01')
Comme Bernhard Vallant l'a dit, si vous voulez un ensemble de requêtes excluant le specified range ends
, vous devriez envisager sa solution , qui utilise gt/lt (supérieur à/inférieur à).
Vous pouvez utiliser Django's filter
with datetime.date
objects :
import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
sampledate__lte=datetime.date(2011, 1, 31))
Lorsque vous créez des plages Django avec un filtre, assurez-vous de connaître la différence entre utiliser un objet de date et un objet de date/heure. __range inclut les dates, mais si vous utilisez un objet datetime pour la date de fin, il n'inclura pas les entrées de ce jour si l'heure n'est pas définie.
startdate = date.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
renvoie toutes les entrées de startdate à enddate, y compris les entrées à ces dates. Mauvais exemple car il renvoie des entrées une semaine dans le futur, mais vous obtenez la dérive.
startdate = datetime.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
il manquera 24 heures d’entrées selon l’heure définie pour les champs de date.
Vous pouvez contourner le "décalage d'impédance" provoqué par le manque de précision de la comparaison d'objet DateTimeField/date
- qui peut se produire si vous utilisez range - en utilisant un datetime.timedelta pour ajouter un jour de retard date dans la gamme. Cela fonctionne comme:
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])
Comme indiqué précédemment, sans que cela ne se produise, les enregistrements sont ignorés le dernier jour.
Edité pour éviter l'utilisation de datetime.combine
- semble plus logique de s'en tenir aux instances de date lors de la comparaison avec un DateTimeField
, au lieu de déconner avec des objets datetime
jetables (et déroutants). Voir plus d'explications dans les commentaires ci-dessous.
Est simple,
YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())
Travaille pour moi
Pour le rendre plus flexible, vous pouvez concevoir un FilterBackend comme ci-dessous:
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
Toujours d'actualité aujourd'hui ... vous pouvez aussi faire:
import dateutil
import pytz
date = dateutil.parser.parse('02/11/2019').replace(tzinfo=pytz.UTC)