[patch] Allow use of *args as well as **kwargs for DB queries
|Reported by:||Owned by:||Adrian Holovaty|
|Component:||Database layer (models, ORM)||Version:|
|Severity:||normal||Keywords:||magic-removal, argument, args, kwargs, Q|
|Cc:||Triage Stage:||Design decision needed|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
This patch is a backwards-compatible extension to the handling of query parameters. It is against the magic-removal branch.
Without this patch, query arguments must be provided as kwargs to get_list, etc. If complex AND/OR queries are required, they must be wrapped in Q() objects, and the complete complex query is provided as a complex= kwarg.
This patch modifies the get_* calls on the Manager to allow the use of *args, as well as kwargs in queries.
This means that Q() objects can be used directly as a query argument. The complex= kwarg continues to work as before. Queries provided as Q() objects are ANDed/merged in the same way that kwargs are handled.
For example, using the new syntax, the query:
polls.get_object( complex= (Q(question__startswith='Who') & (Q(pub_date__exact=date(2005, 5, 2)) | Q(pub_date__exact=date(2005, 5, 6))) )
could also be phrased as:
polls.get_object( Q(question__startswith='Who'), Q(pub_date__exact=date(2005, 5, 2)) | Q(pub_date__exact=date(2005, 5, 6)) )
or, combining the two approaches,
polls.get_object( Q(pub_date__exact=date(2005, 5, 2)) | Q(pub_date__exact=date(2005, 5, 6)), question__startswith='Who' )
NOTE 1: Some query orders become significant, as *args must precede the kwargs. This is the only drawback to this patch, but IMHO, it is something that could be handled through adequate documentation.
NOTE 2: Strictly, queries are not restricted to Q() objects; any object with a get_sql method can be provided as a query. A check for the existence of the get_sql method is made before the query is evaluated.
In addition to implementation code, this patch includes test code, as part of the OR testing package (i.e., the same place complex= is tested)
This patch introduces no incompatibilies in practice - however, in theory, there are some edge case incompatibilities in the get_in_bulk and get_date_list methods. These methods are affected because they already have (and use) *args in an unusual fashion. This patch preserves the important behaviour of these arguments, but the handling of some unusual (and probably erroneous) calling styles may be affected.