如何处理Django中MySQL的"部分"日期(2010-00-00)?

Eti*_*nne 8 python mysql database django date

在我的一个使用MySQL作为数据库的Django项目中,我需要一个日期字段也接受"部分"日期,例如仅年(YYYY)和年和月(YYYY-MM)加上正常日期(YYYY-MM-) DD).

MySQL中的日期字段可以通过接受月份和日期的00来处理.所以2010-00-00在MySQL中有效的,它代表了2010年同样的事情2010-05-00表示2010年5月.

所以我开始创建一个PartialDateField支持这个功能.但是我打了一堵墙,因为默认情况下,Django使用默认的MySQLdb,MySQL的python驱动程序,返回datetime.date一个日期字段的对象并datetime.date()仅支持实际日期.因此,可以修改MySQLdb使用的日期字段的转换器,并仅返回此格式为"YYYY-MM-DD"的字符串.不幸的是,MySQLdb使用的转换器设置在连接级别,因此它用于所有MySQL 日期字段.但Django DateField依赖于数据库返回一个datetime.date对象的事实,所以如果我改变转换器以返回一个字符串,Django根本不开心.

有人有想法或建议来解决这个问题吗?如何PartialDateField在Django中创建一个?

编辑

另外我应该补充一点,我已经考虑了2个解决方案,为年,月和日创建3个整数字段(如Alison R.所述)或使用varchar字段将日期保持为字符串格式为YYYY-MM-DD.

但是在这两个解决方案中,如果我没有错,我会松开日期字段的特殊属性,比如对它们进行此类查询:在此日期之后获取所有条目.我可以在客户端重新实现这个功能,但在我的情况下这不是一个有效的解决方案,因为数据库可以从其他系统查询(mysql客户端,MS Access等)

Eti*_*nne 6

First, thanks for all your answers. None of them, as is, was a good solution for my problem, but, for your defense, I should add that I didn't give all the requirements. But each one help me think about my problem and some of your ideas are part of my final solution.

So my final solution, on the DB side, is to use a varchar field (limited to 10 chars) and storing the date in it, as a string, in the ISO format (YYYY-MM-DD) with 00 for month and day when there's no month and/or day (like a date field in MySQL). This way, this field can work with any databases, the data can be read, understand and edited directly and easily by a human using a simple client (like mysql client, phpmyadmin, etc.). That was a requirement. It can also be exported to Excel/CSV without any conversion, etc. The disadvantage is that the format is not enforce (except in Django). Someone could write 'not a date' or do a mistake in the format and the DB will accept it (if you have an idea about this problem...).

这样,也可以相对容易地完成日期字段的所有特殊查询.对于WHERE的查询:<,>,<=,> =和=直接工作.IN和BETWEEN查询也可以直接工作.对于按日或月查询,您只需要使用EXTRACT(DAY | MONTH ...)进行查询.订购工作也直接.所以我认为它涵盖了所有的查询需求,而且大多没有复杂性.

On the Django side, I did 2 things. First, I have created a PartialDate object that look mostly like datetime.date but supporting date without month and/or day. Inside this object I use a datetime.datetime object to keep the date. I'm using the hours and minutes as flag that tell if the month and day are valid when they are set to 1. It's the same idea that steveha propose but with a different implementation (and only on the client side). Using a datetime.datetime object gives me a lot of nice features for working with dates (validation, comparaison, etc.).

Secondly, I have created a PartialDateField that mostly deal with the conversion between the PartialDate object and the database.

So far, it works pretty well (I have mostly finish my extensive unit tests).