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