我在我的数据库中包含一列以字符串格式(varchar)存储的日期,例如"12-Mar-2011"
,"11-Apr-2012"
等。有没有办法在 Django 中比较这些日期?
在models.py
中,该列被定义为字符串格式。例如:
startdate = models.CharField(max_length=11)
现在我必须将这些日期与日期进行比较。任何帮助表示赞赏。
我在我的数据库中包含一列以字符串格式(varchar)存储的日期,例如"12-Mar-2011"
,"11-Apr-2012"
等。有没有办法在 Django 中比较这些日期?
在models.py
中,该列被定义为字符串格式。例如:
startdate = models.CharField(max_length=11)
现在我必须将这些日期与日期进行比较。任何帮助表示赞赏。
在您的models.py
中,添加一个返回datetime
对象的方法,如下所示:
from datetime import datetime as dt
class SomeModel(models.Model):
# other fields
def startdate_as_date(self):
return dt.strptime(self.startdate,'%d-%b-%Y')
我省略了一些错误检查(例如确保设置了 startdate)并检查日期是否为有效日期 - 您应该稍后添加这些。
现在你可以这样做:
foo = SomeModel.objects.get(pk=1)
the_date = foo.startdate_as_date()
现在the_date
是一个datetime
可用于进行正常比较的对象。
这不是您要寻找的答案,但是...
您确实应该将数据库迁移到使用models.DateField
类型。
除此之外,
objects = YourModel.objects.raw("""
SELECT
STR_TO_DATE(your_string_date_field, '%e-%b-%Y') AS a_mysql_date_field,
*
FROM your_table
""")
做一个原始查询来获取字符串日期作为实际的mysql日期,也许你可以用它来完成你想要做的任何事情。
通过使用 Func、Value 和 MySQL 的 STR_TO_DATE 函数创建自定义管理器并将该管理器添加到您的模型然后对其进行过滤,您完全可以在没有原始 SQL 的情况下完全做您想做的事情。如果您使用 MySQL 或 MariaDB 以外的其他数据库后端,您可能需要相应地更改您提供给 Func 的函数字符串和模式。
管理者.py:
from django.db import models
from django.db.models import Value, Func
class WeirdDateManager(models.Manager):
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.annotate(
start_date = Func(
Value('start_date_string'),
Value('%d-%b-%Y'),
function='STR_TO_DATE',
),
)
return queryset
模型.py:
from .managers import WeirdDateManager
class WeirdDateModel(models.Model):
objects = WeirdDateManager()
start_date_string = models.CharField(db_column="startdate", max_length=11) # I've renamed your field here so that I can use the start_date name to filter on the actual date, not the string.
视图.py:
from .models import WeirdDateModel
objects = WeirdDateModel.objects.filter(start_date__gte = given_date)
您还可以使用注释创建一个新的虚拟字段,以日期时间格式包含您的值。
from django.db.models.expressions import RawSQL
Yourmodel.objects.annotate(startdate_datetime = RawSQL("SELECT STR_TO_DATE(startdate, '%%d-%%b-%%Y')", ())
注意:
%
是因为 RawSQL 函数实际上在内部进行了一些格式化,因此%
必须进行转义。None
如果您的请求无效,则该字段值将是。例如,如果您使用不存在的格式字符或无效的格式值。例如,如果您尝试%m
匹配大于 12 的月份等。