id,summary,reporter,owner,description,type,status,component,version,severity,resolution,keywords,cc,stage,has_patch,needs_docs,needs_tests,needs_better_patch,easy,ui_ux
21863,Consider adding get_transform() to supplement get_lookup(),Anssi Kääriäinen,nobody,"Currently the API for get_lookup() is get_lookup(lookup_name). However, there are situations where a field will need more information to decide if it needs to return a lookup or a transform. Consider HStoreField. A candidate API for HStoreField is that:
- `hstore_field__exact=val` => exact lookup against the hstore_field
- `hstore_field=val` => also exact lookup against the hstore_field
- `hstore_field__exact__exact=val` => get key exact from hstore, do an exact lookup against that
- `hstore_field__nonlookup=val` => get key nonlookup from hstore, do an exact lookup against that
This is similar to how `fk__exact` and `fk__exact__exact` work currently if the model pointed by fk has field named exact.
In addition, we want to support transforms in .values() etc calls in the future. So `hstore_field__exact` should always resolve to transform if used in values().
Currently this is impossible to do. The get_lookup() method doesn't know if there are still further lookups in the path. It knows just the current lookup. If we are resolving path `exact__exact` get_lookup() should return transform for the first `exact`, lookup for the second `exact`. If we are resolving just `exact`, then lookup should be returned for the first 'exact'. When resolving `exact` for `.values('hstorefield__exact')` call in later releases, the `exact` should resolve to transform.
If we add get_transform() method we could change the lookup resolution code in the ORM to do:
- for non-final lookups: always use get_transform()
- for final lookup in filter() calls: try get_lookup(lookup_name). If that doesn't return anything, use get_transform(lookup_name) + get_lookup('exact').
- for any lookup in .values() etc calls: always use get_transform()
The above examples would be resolved as follows:
- `hstorefield__exact=val`: get_lookup('exact') -> match, so use exact lookup against hstorefield
- `hstorefield=val`: get_lookup('exact') -> same as above
- `hstorefield__exact__exact=val`: get_transform('exact'), get_lookup('exact') -> match, so use exact lookup against key exact of hstorefield
- `hstorefield__nonlookup=val`: get_lookup('nonlookup') -> no match, so try get_transform('nonlookup') + get_lookup('exact') -> exact lookup against key nonlookup
The values() call will use always get_transform() so `.values('hstorefield__exact`)` will work correctly.
There might also be need to add register_transform() method. If we have only register_lookup() but methods get_lookup() and get_transform() it might lead to some confusion.
Adding register_transform() will break the API, but that is hopefully OK during alpha.",New feature,closed,"Database layer (models, ORM)",1.7-alpha-1,Normal,fixed,,,Accepted,1,1,0,0,0,0