Opened 11 years ago
Last modified 10 years ago
#22536 new Bug
Exceptions using date-based generic views with MySQL, USE_TZ=True and bad data
Reported by: | Chris Adams | Owned by: | Chris Adams |
---|---|---|---|
Component: | Generic views | Version: | 1.5 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Pull Requests: | How to create a pull request | ||
Description (last modified by ) ¶
I ran into a non-obvious exception while using the date-based generic views. get_previous_day / get_next_day were raising an AttributeError ('NoneType' object has no attribute 'astimezone') in the following code when the view was called with the earliest item in the system:
try: result = getattr(qs[0], date_field) except IndexError: return None # Convert datetimes to dates in the current time zone. if generic_view.uses_datetime_field: if settings.USE_TZ: result = timezone.localtime(result) result = result.date()
This error wasn't immediately obvious because the query shouldn't have been able to return a NULL. Looking at the data revealed the problem: a small number of records on my test instance had invalid dates in MySQL (0000-00-00) which were included by the lt query but subsequently converted into None by the ORM.
The nature of the bug suggests that the cleanest patch might simply be an immediate "if not result: return None", perhaps with a warning about invalid data.
According to the ticket's flags, the next step(s) to move this issue forward are:
- To provide a patch by sending a pull request. Claim the ticket when you start working so that someone else doesn't duplicate effort. Before sending a pull request, review your work against the patch review checklist. Check the "Has patch" flag on the ticket after sending a pull request and include a link to the pull request in the ticket comment when making that update. The usual format is:
[https://github.com/django/django/pull/#### PR]
.
Change History (2)
comment:1 by , 11 years ago
Description: | modified (diff) |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 10 years ago
If we want to be nice there's another case which could be handled here. I just lost hours to debugging a crash which happened because result
was a naive datetime. This was probably the result of a conversion of MySQL to PostgreSQL done without the help of Django, because (as the documentation says) Django always created datetime fields with timezones.
A thing which would have helped me would have been an error message along the lines of "Time zone missing on %(result)s. Your database is broken."
The error message for later reference: ValueError: astimezone() cannot be applied to a naive datetime
.
(At least this comment might point someone else in the correct direction.)
We discussed this ticket on IRC. I believe it's an acceptable solution, provided there's an adequate comment and a MySQL-specific test. The code isn't complex, so this change is low risk.