我有以下型号
class Destination_Deal(models.Model):
name = models.CharField(_("Nombre"),max_length=200)
class Departure_Date(models.Model):
date_from= models.DateField(_('Desde'))
date_to= models.DateField(_('Hasta'))
destination_deal = models.ForeignKey(Destination_Deal,verbose_name = _("Oferta de Destino"))
这是表departure_date
中的实际数据id date_from date_to destination_deal_id
1 2012-11-01 2013-03-17 1
2 2012-11-01 2012-12-16 2
3 2012-09-16 2012-10-31 3
4 2012-11-01 2012-12-16 3
5 2013-01-04 2013-01-11 4
如果指定的月份和年份介于date_from和date_to之间,我想过滤Destination_Deals。
示例1
月:九月(09)
年份:2012年
通缉出发日期结果:
ID 3:这是触及09/2012的唯一数据范围
示例2
月:2月(02)
年份:2013年
通缉出发日期结果:
ID 1:02/2012是在03/2012之前的
所以,这一天实际上并不重要。如果月份和年份介于date_from和date_to之间,即使它是一天,也必须过滤。
我想我必须使用像this这样的东西,但我不知道该怎么做。
提前致谢! 米格尔
--- ---编辑
这是对Aamir Adnan答案的测试,但它没有像我预期的那样工作,因为它从2012年11月到2013年3月也必须被返回,因此2013年1月介于。之间。
Departure_Date.objects.all()
[<Departure_Date: id: 1 - from: 2012-11-01 - to: 2013-03-17>,
<Departure_Date: id: 2 - from: 2012-11-01 - to: 2012-12-16>,
<Departure_Date: id: 3 - from: 2012-09-16 - to: 2012-10-31>,
<Departure_Date: id: 4 - from: 2012-11-01 - to: 2012-12-16>,
<Departure_Date: id: 5 - from: 2013-01-04 - to: 2013-01-11>]
month:1
year:2013
where = '%(year)s >= YEAR(date_from) AND %(month)s >= MONTH(date_from) \
AND %(year)s <= YEAR(date_to) AND %(month)s <= MONTH(date_to)' % \
{'year': year, 'month': month}
Departure_Date.objects.extra(where=[where])
[<Departure_Date: id: 5 - from: 2013-01-04 - to: 2013-01-11>]
答案 0 :(得分:47)
year = 2012
month = 09
Departure_Date.objects.filter(date_from__year__gte=year,
date_from__month__gte=month,
date_to__year__lte=year,
date_to__month__lte=month)
使用.extra
的替代方法:
where = '%(year)s >= YEAR(date_from) AND %(month)s >= MONTH(date_from) \
AND %(year)s <= YEAR(date_to) AND %(month)s <= MONTH(date_to)' % \
{'year': year, 'month': month}
Departure_Date.objects.extra(where=[where])
有一种特殊情况,上述查询无法产生预期的结果。
例如:
date_from='2012-11-01'
date_to='2013-03-17'
and input is
year=2013
month=1
然后%(month)s >= MONTH(date_from)
条件错误,因为第1个月是&lt; date_from
中的第11个月,但年份不同,因此需要MySQL IF
条件:
where = '%(year)s >= YEAR(date_from) AND IF(%(year)s > YEAR(date_from), \
IF(%(month)s > MONTH(date_from), %(month)s >= MONTH(date_from), %(month)s < MONTH(date_from)), \
IF(%(month)s < MONTH(date_from), %(month)s < MONTH(date_from), %(month)s >= MONTH(date_from))) \
AND %(year)s <= YEAR(date_to) \
AND %(month)s <= MONTH(date_to)' % \
{'year': year, 'month': month}
Departure_Date.objects.extra(where=[where])
答案 1 :(得分:3)
仅使用python代码的解决方案。主要思想是使用python构造date_from和date_to。然后,filter
与__lte
和__gte
:
import calendar
from datetime import datetime
from django.db.models import Q
def in_month_year(month, year):
d_fmt = "{0:>02}.{1:>02}.{2}"
date_from = datetime.strptime(
d_fmt.format(1, month, year), '%d.%m.%Y').date()
last_day_of_month = calendar.monthrange(year, month)[1]
date_to = datetime.strptime(
d_fmt.format(last_day_of_month, month, year), '%d.%m.%Y').date()
return Departure_Date.objects.filter(
Q(date_from__gte=date_from, date_from__lte=date_to)
|
Q(date_from__lt=date_from, date_to__gte=date_from))
现在这将有效:
>>> Departure_Date.objects.all()
[<Departure_Date: id: 1 - from: 2012-11-01 - to: 2013-03-17>,
<Departure_Date: id: 2 - from: 2012-11-01 - to: 2012-12-16>,
<Departure_Date: id: 3 - from: 2012-09-16 - to: 2012-10-31>,
<Departure_Date: id: 4 - from: 2012-11-01 - to: 2012-12-16>,
<Departure_Date: id: 5 - from: 2013-01-04 - to: 2013-01-11>]
>>> in_month_year(month=1, year=2013)
[<Departure_Date: id: 1 - from: 2012-11-01 - to: 2013-03-17>,
<Departure_Date: id: 5 - from: 2013-01-04 - to: 2013-01-11>]
答案 2 :(得分:0)
你可以绕过&#34;阻抗不匹配&#34;由于DateTimeField/date
对象比较缺乏精确度导致 - 如果使用范围 - 可以通过使用 datetime.timedelta 将一天添加到该范围内的最后日期。这就像:
import datetime
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])