Django,按日期范围内指定的年和月过滤

fdbelqdn  于 2022-12-30  发布在  Go
关注(0)|答案(4)|浏览(173)

我有以下型号

  1. class Destination_Deal(models.Model):
  2. name = models.CharField(_("Nombre"),max_length=200)
  3. class Departure_Date(models.Model):
  4. date_from= models.DateField(_('Desde'))
  5. date_to= models.DateField(_('Hasta'))
  6. destination_deal = models.ForeignKey(Destination_Deal,verbose_name = _("Oferta de Destino"))

这是表deviation_date中的实际数据

  1. id date_from date_to destination_deal_id
  2. 1 2012-11-01 2013-03-17 1
  3. 2 2012-11-01 2012-12-16 2
  4. 3 2012-09-16 2012-10-31 3
  5. 4 2012-11-01 2012-12-16 3
  6. 5 2013-01-04 2013-01-11 4

如果指定的月份和年份介于date_from和date_to之间,我想过滤Destination_Deals。

    • 示例1**

月份:9月(09)
年份:2012年

    • 想要的出发日期结果:**

ID 3:这是唯一触及09/2012的数据范围

    • 示例2**

月份:2月(02)
年份:2013年

    • 想要的出发日期结果:**

ID 1:2012年2月在2012年3月之前
因此,日期实际上并不重要。如果月份和年份介于date_from和date_to之间,即使是一天,也必须过滤。
我想我一定要用这样的东西,但我不知道该怎么做。

  • ---编辑---*

这是对Aamir Adnan答案的测试,但它没有像我预期的那样工作,因为ID 1也必须返回,因为它从2012年11月到2013年3月,所以2013年1月介于两者之间。

  1. Departure_Date.objects.all()
  2. [<Departure_Date: id: 1 - from: 2012-11-01 - to: 2013-03-17>,
  3. <Departure_Date: id: 2 - from: 2012-11-01 - to: 2012-12-16>,
  4. <Departure_Date: id: 3 - from: 2012-09-16 - to: 2012-10-31>,
  5. <Departure_Date: id: 4 - from: 2012-11-01 - to: 2012-12-16>,
  6. <Departure_Date: id: 5 - from: 2013-01-04 - to: 2013-01-11>]
  7. month:1
  8. year:2013
  9. where = '%(year)s >= YEAR(date_from) AND %(month)s >= MONTH(date_from) \
  10. AND %(year)s <= YEAR(date_to) AND %(month)s <= MONTH(date_to)' % \
  11. {'year': year, 'month': month}
  12. Departure_Date.objects.extra(where=[where])
  13. [<Departure_Date: id: 5 - from: 2013-01-04 - to: 2013-01-11>]
4jb9z9bj

4jb9z9bj1#

查看文档

  1. year = 2012
  2. month = 09
  3. Departure_Date.objects.filter(date_from__year__gte=year,
  4. date_from__month__gte=month,
  5. date_to__year__lte=year,
  6. date_to__month__lte=month)

使用.extra的替代方法:

  1. where = '%(year)s >= YEAR(date_from) AND %(month)s >= MONTH(date_from) \
  2. AND %(year)s <= YEAR(date_to) AND %(month)s <= MONTH(date_to)' % \
  3. {'year': year, 'month': month}
  4. Departure_Date.objects.extra(where=[where])

有一种特定的情况,上面的查询没有产生所需的结果。
例如:

  1. date_from='2012-11-01'
  2. date_to='2013-03-17'
  3. and input is
  4. year=2013
  5. month=1

那么%(month)s >= MONTH(date_from)条件是错误的,因为在date_from中第1个月〈第11个月,但是年份不同,所以这里需要MySQL IF条件:

  1. where = '%(year)s >= YEAR(date_from) AND IF(%(year)s > YEAR(date_from), \
  2. IF(%(month)s > MONTH(date_from), %(month)s >= MONTH(date_from), %(month)s < MONTH(date_from)), \
  3. IF(%(month)s < MONTH(date_from), %(month)s < MONTH(date_from), %(month)s >= MONTH(date_from))) \
  4. AND %(year)s <= YEAR(date_to) \
  5. AND %(month)s <= MONTH(date_to)' % \
  6. {'year': year, 'month': month}
  7. Departure_Date.objects.extra(where=[where])
展开查看全部
wkyowqbh

wkyowqbh2#

仅使用python代码的解决方案。主要思想是用python构造date_from和date_to。然后这些日期可以在filter中与__lte__gte一起使用:

  1. import calendar
  2. from datetime import datetime
  3. from django.db.models import Q
  4. def in_month_year(month, year):
  5. d_fmt = "{0:>02}.{1:>02}.{2}"
  6. date_from = datetime.strptime(
  7. d_fmt.format(1, month, year), '%d.%m.%Y').date()
  8. last_day_of_month = calendar.monthrange(year, month)[1]
  9. date_to = datetime.strptime(
  10. d_fmt.format(last_day_of_month, month, year), '%d.%m.%Y').date()
  11. return Departure_Date.objects.filter(
  12. Q(date_from__gte=date_from, date_from__lte=date_to)
  13. |
  14. Q(date_from__lt=date_from, date_to__gte=date_from))

现在这将工作:

  1. >>> Departure_Date.objects.all()
  2. [<Departure_Date: id: 1 - from: 2012-11-01 - to: 2013-03-17>,
  3. <Departure_Date: id: 2 - from: 2012-11-01 - to: 2012-12-16>,
  4. <Departure_Date: id: 3 - from: 2012-09-16 - to: 2012-10-31>,
  5. <Departure_Date: id: 4 - from: 2012-11-01 - to: 2012-12-16>,
  6. <Departure_Date: id: 5 - from: 2013-01-04 - to: 2013-01-11>]
  7. >>> in_month_year(month=1, year=2013)
  8. [<Departure_Date: id: 1 - from: 2012-11-01 - to: 2013-03-17>,
  9. <Departure_Date: id: 5 - from: 2013-01-04 - to: 2013-01-11>]
展开查看全部
krugob8w

krugob8w3#

您可以通过使用datetime.timedelta向范围中的最后一个日期添加一天来避免由于DateTimeField/date对象比较中缺乏精度而导致的“阻抗不匹配”(如果使用range,则可能发生这种情况)。

  1. import datetime
  2. start = date(2012, 12, 11)
  3. end = date(2012, 12, 18)
  4. new_end = end + datetime.timedelta(days=1)
  5. ExampleModel.objects.filter(some_datetime_field__range=[start, new_end])
wvyml7n5

wvyml7n54#

您可以使用__gte__lte的2个过滤器:

  1. import datetime as dt
  2. start = dt.date(2012, 12, 11)
  3. end = dt.date(2012, 12, 18)
  4. ExampleModel.objects.filter(date_field__gte=start).filter(date_field__lte=end)

相关问题