根据Django中的子字符串过滤DateField

时间:2018-11-04 15:49:38

标签: django python-3.x

因此,我正在使用SELECT agl.grade, COUNT(d.two) FROM (SELECT 1 AS grade UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6) AS agl LEFT JOIN data AS d ON d.two = agl.grade AND d.date >= '2018-10-23 00:00:00' AND d.date < '2018-10-23 23:59:59' GROUP BY agl.grade 来显示日期。使用上下文传递给模板时,其以DateField

的格式呈现

现在数据库中有多个此类日期的条目。我想根据实际显示的日期的字符串进行过滤。也就是说,当我在搜索输入字段中输入Nov. 4, 2018Nov 4nov 4时,它应该显示匹配的结果。更像是子字符串匹配。

现在唯一的问题是我不知道如何将NOV 4字段转换为my_model.date

Nov. 4, 2018返回2016-11-04,我不想用str(my_model.date)映射来解析

我认为,两种解决方案中的任何一种都应该起作用。

1)允许我这样做的Django过滤器。

2)将month_number-to-month_name转换为my_model.date字符串

请帮助,现在一直被困在此

1 个答案:

答案 0 :(得分:1)

因为您特别提到在模板中显示日期,所以我不确定您所指的搜索操作是前端,面向用户的操作还是后端数据库查询。

如果要在显示之前将my_model.date转换为漂亮的字符串,然后再发送至模板,则可以使用strptime在视图中对其进行处理-这将使您获得控制权str包装器缺少的内容:https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior尽管有些模板标签也可以为您做到这一点,但在您的视图中这样做更快,更好。

如果这是一个数据库查询,请记住,您可以按日期对象的属性过滤日期对象。例如,要获取所有在2011年11月11日创建的实例:

MyModel.objects.filter(
    date__day = 11, 
    date__month = 11,
    date__year = 2018
)

请注意双下划线。


现在,我更好地了解了您的目标,回复您的评论:

日期字段不会在可查询的地点中存储其更多的“详细”日期信息。如果要查询“ Nov”之类的内容而不是11,则需要在模型中添加另一个(或多个)属性,以将计算出的数据传播到可查询的容器中。

如果是我,我会在my_model内这样做:

from datetime import date

...

rawDate = models.DateField(...) #your current date field
formatted_month = models.CharField(...)
formatted_day = models.IntegerField(...)
formatted_year = models.IntegerField(...)

...

def save(self):
    self.formatted_month = date.strftime(self.rawDate, '%b')
    self.formatted_day = date.strftime(self.rawDate, '%d')
    self.formatted_year = date.strftime(self.rawDate, '%Y')
    super().save()

现在,您可以像这样执行NOV/nov/Nov查找:

MyModel.objects.filter(
    formatted_month__iexact = 'Nov'
)

这仍然需要您在点击数据库之前先在搜索词中划分月份和日期。如果您想将其压缩一下,可以将所有格式化的日期信息存储在单个字段中:

formatted_date = models.CharField(...)
...
def save(self):
    self.formatted_date = date.strftime(self.rawDate, '%b %d %Y')

然后,如果您的查询看起来像“ NOV 4”,则可以执行以下操作:

MyModel.objects.filter(formatted_date__icontains='NOV 4')