Le 1 nov. 2011 à 15:58, Aymeric Augustin <aymeric.augus...@polytechnique.org> a 
écrit :
> 
> There is only one outstanding issue that I know of. `QuerySet.dates()` 
> operates in the database timezone, ie. UTC, while an end user would expect it 
> to take into account its current time zone. This affects `date_hierarchy` in 
> the admin and the date based generic views. The same problem also exists for 
> the `year`, `month`, `day`, and `week_day` lookups.


Fifteen months later, I finally got around to fixing this. I would appreciate 
(1) a review (2) tests under Oracle.

Ticket : https://code.djangoproject.com/ticket/17260
Patch: https://github.com/django/django/pull/715

The changes are quite involved — I didn't implement this originally for a 
reason :)

** Changes **

1) Add a new method QuerySet.datetimes(). This method takes a tzinfo argument 
that says in which time zone datetimes should be converted prior to truncation 
and aggregation. It defaults to the current time zone, which will produce the 
expected results in general.

2) Add plumbing to the ORM to pass the tzinfo argument down to the SQL 
generation layer, where database specific features are used to perform the time 
zone conversion within the database.

3) Make QuerySet.dates() return dates instead of datetimes. This is a backwards 
incompatible change, but:
        - I don't want a method called "dates" to return aware datetimes;
        - Real code may still work thanks to duck-typing;
        - Replacing .dates() with .datetimes() is trivial.

4) Prevent QuerySet.dates() from operating on datetime fields. This is a 
backwards incompatible change, but:
        - The restriction is only enforced when USE_TZ is True;
        - It's necessary to stop mixing dates and datetimes unsafely when 
USE_TZ is True;
        - QuerySet.dates() returned incorrect results in 1.4 and 1.5 when 
USE_TZ was True anyway.

5) Add __hour, __minute and __second lookups, and make all lookups on datetime 
fields in the current time zone. There's no way to pass an explicit time zone 
to the lookups,  but the current time zone can be overridden if necessary. 
There's some special handling for __year lookups because they're translated to 
__range lookups. This is backwards incompatible if someone has fields named 
hour, minute or second.

** Database support **

- PostgreSQL / PostGIS: everything works.
- SQLite: everything works, requires pytz; Spatialite: untested.
- MySQL / MySQL GIS: everything works, requires loading the time zone 
definitions.
- Oracle / Oracle GIS: untested.

A database feature called "has_zoneinfo_database" says if the time zone 
definitions are available.

** Remarks **

There are similar code paths for dates and datetimes, which result in some code 
duplication. I've tried to minimize it through subclassing wherever possible.

It's weird to add the time zone parameter in SQLDateTimeCompiler.as_sql. This 
hack is necessary because the ORM doesn't handle parameters for select 
expressions. For example, SQLCompiler.get_columns returns "sql", unlike 
get_from_clause which returns "sql, params".

Thanks,

-- 
Aymeric.



-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to