Eu tenho um campo em um modelo como:
class Sample(models.Model):
date = fields.DateField(auto_now=False)
Agora, preciso filtrar os objetos por um período.
Como filtrar todos os objetos que possuem uma data entre 1-Jan-2011e 31-Jan-2011?
Eu tenho um campo em um modelo como:
class Sample(models.Model):
date = fields.DateField(auto_now=False)
Agora, preciso filtrar os objetos por um período.
Como filtrar todos os objetos que possuem uma data entre 1-Jan-2011e 31-Jan-2011?
Respostas:
Usar
Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])
Ou se você está apenas tentando filtrar os meses:
Sample.objects.filter(date__year='2011',
date__month='01')
Como Bernhard Vallant disse, se você quiser um conjunto de consultas que exclua a opção specified range ends, considere a solução dele , que utiliza gt / lt (maior que / menor que).
__rangeinclui as fronteiras (como sql de BETWEEN), se você não quer que as fronteiras incluídos você teria que ir com o meu gt / solução lt ...
order_bysobre o gerado QuerySetpelo mencionado acima filter. Eu não uso o Django há anos.
Você pode usar django'sfilter com datetime.dateobjetos :
import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
sampledate__lte=datetime.date(2011, 1, 31))
Ao fazer intervalos de django com um filtro, verifique se você sabe a diferença entre usar um objeto de data e um objeto de data e hora. __range é inclusivo nas datas, mas se você usar um objeto datetime para a data final, ele não incluirá as entradas para esse dia se o horário não estiver definido.
startdate = date.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
retorna todas as entradas da data inicial até a data final, incluindo as entradas nessas datas. Exemplo ruim, pois isso está retornando entradas de uma semana para o futuro, mas você entende.
startdate = datetime.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
faltam 24 horas no valor de entradas, dependendo da hora definida para os campos de data.
dateobjeto: >>> from datetime import date >>> startdate = date.today()
Você pode contornar a "incompatibilidade de impedância" causada pela falta de precisão na DateTimeField/datecomparação de objetos - que pode ocorrer se o intervalo for usado - usando um datetime.timedelta para adicionar um dia à última data no intervalo. Isso funciona como:
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])
Como discutido anteriormente, sem fazer algo assim, os registros são ignorados no último dia.
Editado para evitar o uso de datetime.combine- parece mais lógico ficar com instâncias de data ao comparar com a DateTimeField, em vez de mexer com datetimeobjetos descartáveis (e confusos) . Veja mais explicações nos comentários abaixo.
Example.objects.filter(created__range=[date(2014, 1, 1), date(2014, 2, 1)]), não incluiria objetos criados date(2014, 2, 1), como o @cademan explicou útil. Mas se você incrementasse a data de término adicionando um dia, obteria um conjunto de consultas cobrindo os objetos ausentes (e omitindo convenientemente objetos criados por date(2014, 2, 2)causa da mesma peculiaridade). A coisa chata aqui é que um intervalo 'manual' especificado com created__gte ... created__lte=date(2014, 2, 1)também não funciona, o que é definitivamente IMHO contra-intuitivo.
É simples,
YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())
Funciona para mim
Para torná-lo mais flexível, você pode criar um FilterBackend como abaixo:
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
Ainda relevante hoje. Você também pode fazer:
import dateutil
import pytz
date = dateutil.parser.parse('02/11/2019').replace(tzinfo=pytz.UTC)