Changeset 3525

Show
Ignore:
Timestamp:
10/19/07 15:14:07 (1 year ago)
Author:
roger
Message:

Fixed pagination of Query objects (sqlalchemy), thanks to Jonathan Hitchcock and Remi Jolin (#1434).

Paginate can now order a SA Query object by attributes from related objects (#1582).
Notice that it only works with SQLAlchemy 0.3.x at the moment... (see: #1591).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.0/CHANGELOG.txt

    r3510 r3525  
    88*Features* 
    99    * "tg-admin sql" is now more powerful for SQLAlchemy. Ticket #1418 
     10    * Paginate allows ordering by attributes from related objects (SQLAlchemy 
     11      Query objects only). Ticket #1582. 
    1012 
    1113*Fixes* 
    1214    * Ticket #1185: rollback SA transaction if a controller method fails, and it 
    1315      has an exception_handler. 
    14     * sa_rwt (SQLAlchemy run with transaction) refactored to fix some corner  
     16    * sa_rwt (SQLAlchemy run with transaction) refactored to fix some corner 
    1517      cases. 
    16     * Ticket #1508: fixed internal pagination ordering, avoiding a potential  
     18    * Ticket #1508: fixed internal pagination ordering, avoiding a potential 
    1719      error when paginating Query objects (sqlalchemy) and ordering by 4 or more 
    1820      columns. 
     21    * Ticket #1434: Fixed pagination of Query objects (SQLAlchemy). The first 
     22      patch assumed that Query objects have a _query attribute which holds the 
     23      query object, which is only true for SelectResults objects. 
    1924 
    2025*Contributors* 
    2126 
    22 Paul Johnston, Roger Demetrescu 
     27Paul Johnston, Remi Jolin, Jonathan Hitchcock, Roger Demetrescu 
    2328 
    2429 
     
    7479        * ticket #1434. Now handles SA Query in addition of SelectResults 
    7580      which will be deprecated in the near future. 
    76          
     81 
    7782        * ticket #1325  Fix visit entries created more than once in the 
    7883          database. 
     
    123128* make 'flash' block dynamic in quickstart 
    124129* session setting is moved to config/app.cfg 
    125 * command/toolbox info could list the toolbox plugins  
     130* command/toolbox info could list the toolbox plugins 
    126131* Enhancement SQLAlchemy default model, use 'assign' to avoid repeatedly writing, thanks cito 
    127132* Able to specify a default doctype in genshi, thanks Alastair Houghton 
     
    140145* Fixed bug in tg-admin that caused it not to operate properly on projects deployed as eggs. Patch 
    141146  from #1361 by Christoph Zwerschke. 
    142 * SA auto-commiting fixed in some rare circumstances where sa_rwt was not being called. Patch from  
     147* SA auto-commiting fixed in some rare circumstances where sa_rwt was not being called. Patch from 
    143148  #1267 by Paul Johnston. 
    144 * CatWalk now handles customized addRemoveName in SO. #911 by Joost  
     149* CatWalk now handles customized addRemoveName in SO. #911 by Joost 
    145150* using base64.decodestring in visitor.py for 2.3 compatibility. #1279 by Paul Fisher. 
    146151* Config file in quickstarted app now has config option to load identity classes. Thanks to Felix 
    147152  Schwarz #1255. 
    148153* Identity now supports encrypted passwords with unicode characters. Thanks to Felix Schwarz and 
    149   Patrick Lewis #1281  
     154  Patrick Lewis #1281 
    150155* minor changes to template so they work properly when server.webpath != / thanks to "nludban" #1213 
    151156* fix quickstart project tests, thanks to Christoph Zwerschke #1289, Jeff Kowalczyk #1219 
     
    163168* FormEncode version to i18n aware 0.7.1 
    164169* RuleDispatch to 0.5a0.dev-r2303 for Python 2.5 support. 
    165 * Added requirement of DecoratorTools due to upgrade of PyProtocols which  
     170* Added requirement of DecoratorTools due to upgrade of PyProtocols which 
    166171  deprecates functions used in decorator.py. 
    167172 
     
    178183* paginate decorator now supports SA, improves sorting and fixes problems 
    179184  with CompoundWidget. Thanks to randall@tnr.cc and sbr77. #2404 
    180 * Catwalk now supports SQLMultipleJoin/SQLRelatedJoins. Thanks to Chris Arndt  
     185* Catwalk now supports SQLMultipleJoin/SQLRelatedJoins. Thanks to Chris Arndt 
    181186  #2382 
    182187* more docstring for widgets package #2355 
     
    187192* Identity logout  now works properly when using ``set_identity_user`` #1245. 
    188193  Thanks to Felix Schwarz 
    189 * set right default encoding 'utf-8' instead of 'utf8' which broke  
     194* set right default encoding 'utf-8' instead of 'utf8' which broke 
    190195  XmlHttpRequest in IE. Thanks Simon King #2408 
    191196* workaround for MySQLdb imcompatibilty with MySQL 4.1. Thanks to Felix Schwarz 
     
    196201* fixes for FR locale in JavaScript for CalendarPicker. Thanks to Florent Aide 
    197202  #2370 
    198 * various test case fixes. Thanks to Christoph Zwerschke, Felix Schwarz  
     203* various test case fixes. Thanks to Christoph Zwerschke, Felix Schwarz 
    199204  #2366 #2374 #2376 
    200 * adapt tests to changes in Kid 0.9.4. Thanks to Jeff Hinrichs and  
     205* adapt tests to changes in Kid 0.9.4. Thanks to Jeff Hinrichs and 
    201206  Christoph Zwerschke #2364 
    202207* reverted #2256 which caused a RuntimeError #2340 
     
    217222* now possible to pass any option (besides dburi and echo) to sqlalchemy 
    218223  engine. Thanks to elftherios and Lee McFadden #2318 #2320 
    219 * now possible to place test specific configuration in "test.cfg". Thanks to  
     224* now possible to place test specific configuration in "test.cfg". Thanks to 
    220225  Tim Freund #2263 
    221226* support testing the code that uses identity. Thanks to Max Ischenko and 
     
    225230*Features* 
    226231 
    227 * now possible to add variables to the root template namespace via  
     232* now possible to add variables to the root template namespace via 
    228233  turbogears.view.root_variable_providers. Thanks Arnar Birgisson #2261 
    229234* turbogears.database.run_with_transaction is now a MultiorderGenericFunction to 
     
    236241* Fix implicit transactions for SQLAlchemy. Thanks to Lee McFadden #2322 
    237242* Various CSS fixes for DataGrid. Thanks Florent Aide #2316 
    238 * FeedController is now a Controller so tg.url works properly and fixed missing  
     243* FeedController is now a Controller so tg.url works properly and fixed missing 
    239244  import in feed.py .Thanks Florent Aide #2310 #2312 
    240245* Looser Enum implementation taht works better with ToscaWidgets #2303 
     
    244249* throwing an identity.IdentityException inside a controller method is now 
    245250  caught by identity.SecureResource #2250 
    246 * various test case fixes. Thanks to Felix Schwarz, Joost Moesker,  
     251* various test case fixes. Thanks to Felix Schwarz, Joost Moesker, 
    247252  Jeff Kowalczyk #2247 #2266 #2268 #2314 
    248253* 'logout' method in SQLObjectIdentity was setting read-only property. Does not 
     
    383388* Former LocalizableJSLink is now CalendarLangFile. New LocalizableJSLink is 
    384389  simpler but backwards-incompatible. 
    385 * Catwalk no longer accepts an allowHost argument.  
     390* Catwalk no longer accepts an allowHost argument. 
    386391  To restrict access to it use Identity.SecureObject instead. 
    387    
     392 
    388393*Deprecations* 
    389394 
    390395* Use of "entrys" is now deprecated in the FeedController. You should use 
    391396  "entries" instead. 
    392     
     397 
    393398*Features* 
    394399 
     
    405410* `tg-admin shell` now asks if it should commit changes to the database on exit. 
    406411* Widgets can be listed at the `tg.include_widgets` config. list to send them to 
    407   every template (a la `tg.mochikit_all`).  
     412  every template (a la `tg.mochikit_all`). 
    408413* `DBTest` now drops tables after each test so they don't interfere with others. 
    409414* Toolbox is now secured using Identity 
     
    420425* `DateTimeConverter` now handles dates < 1900. 
    421426* Catwalk now handles gracefully UnicodeCols. 
    422 * QUICKSTART: `start-project.py` now detects correct python binary's path in  
     427* QUICKSTART: `start-project.py` now detects correct python binary's path in 
    423428  the system. 
    424429* Kid's base templates are now (re)loaded properly. 
     
    442447(My apologies if your name belongs here and is not!) 
    443448 
    444 Roger Demetrescu, Elvelind Grandin, Rune Hansen, Sean De La Torre,  
    445 Alberto Valverde, Max Ischenko, Joseph Tate, Elvelind Grandin,  
     449Roger Demetrescu, Elvelind Grandin, Rune Hansen, Sean De La Torre, 
     450Alberto Valverde, Max Ischenko, Joseph Tate, Elvelind Grandin, 
    446451Charles Duffy, Matt Good, Ksenia Marasanova. 
    447452 
     
    459464* In widgets, if you were using a dictionary as a params be aware that now 
    460465  the dictionary is not updated at construction or display/render time but 
    461   simply replaced with the new one.  
    462   If you were using it to provide default attributes for your widget, take a  
     466  simply replaced with the new one. 
     467  If you were using it to provide default attributes for your widget, take a 
    463468  look at how the TableForm does that. 
    464469 
     
    470475  precision.) 
    471476* tg-admin info shows which eggs require TurboGears 
    472 * In widgets, SelectionField now supports grouped options,  
     477* In widgets, SelectionField now supports grouped options, 
    473478  SingleSelectField and MultipleSelectField widgets take advantage of this 
    474479  to provide an optgroup tag. The format of a grouped options list is like 
    475480  the following: 
    476   
     481 
    477482  options = [(None, [(1, "a"), (2, "b")]), ("Others", [(3, "c"), (4, "d")])] 
    478483 
     
    491496* Package name is used instead of `your_project` in the quickstart 
    492497  logging config. 
    493    
     498 
    494499*Fixes* 
    495500 
     
    528533Max Ischenko, Claudio Martinez, Matt Good, Rune Hansen, Michele Cella, 
    529534Jorge Godoy, Alberto Valverde González, Simon Belak, Jeroen Dekkers, 
    530 Mark Ramm-Christensen, Ronald Jaramillo,  
     535Mark Ramm-Christensen, Ronald Jaramillo, 
    531536Richard Standbrook, Roger Demetrescu, Patrick Lewis, Hal Wine, 
    532537Jorge Vargas, Bob Kuehne. 
     
    575580* For Python 2.3 users, there is a convenient new decorator syntax 
    576581  that comes from Phillip Eby's PEAK. 
    577    
     582 
    578583Here's is the equivalent of @expose(): 
    579584 
  • branches/1.0/turbogears/paginate.py

    r3510 r3525  
    342342        col = getattr(var_data.sourceClass.q, colname, None) 
    343343 
    344     elif isinstance(var_data, SASelectResults) or isinstance(var_data, Query)
     344    elif isinstance(var_data, SASelectResults)
    345345        col = getattr( 
    346346                var_data._query.mapper.c, 
     
    348348                None) 
    349349 
     350    elif isinstance(var_data, Query): 
     351        col = getattr( 
     352                var_data.mapper.c, 
     353                colname[len(var_data.mapper.column_prefix or ''):], 
     354                None) 
     355        #if no attribute is found, let's try searching for 'foreign' objects... 
     356        # eg.: address.user.occupation.name 
     357        if not col and colname.find('.'): 
     358            seq = colname.split('.') 
     359            mapper = var_data.mapper 
     360            for propname in seq[:-1]: 
     361                prop = mapper.properties.get(propname) 
     362                if not prop: 
     363                    break 
     364                mapper = prop.mapper 
     365            # last item from split should be a simple attribute 
     366            col = getattr( 
     367                    mapper.c, 
     368                    seq[-1][len(mapper.column_prefix or ''):], 
     369                    None) 
    350370    else: 
    351371        raise StandardError, 'expected SelectResults' 
     
    372392 
    373393# Ordering re: 
    374 ordering_expr = re.compile(r"('\w+'): ?\[(\d+), ?(True|False)\]") 
     394ordering_expr = re.compile(r"('\w+(\.\w+)*'): ?\[(\d+), ?(True|False)\]") 
    375395 
    376396def convert_ordering(ordering): 
     
    392412            for ordering_info in ordering_info_find: 
    393413                ordering_key = str(ordering_info[0]).strip("'") 
    394                 ordering_order = int(ordering_info[1]) 
    395                 ordering_reverse = bool(ordering_info[2] == 'True') 
     414                ordering_order = int(ordering_info[2]) 
     415                ordering_reverse = bool(ordering_info[3] == 'True') 
    396416                new_ordering[ordering_key] = [ordering_order, 
    397417                                              ordering_reverse]