Opened 19 years ago
Closed 18 years ago
#3746 closed (wontfix)
Add a wildcard object for use in objects.filter queries.
| Reported by: | Owned by: | Adrian Holovaty | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev | 
| Severity: | Keywords: | wildcard filter query | |
| Cc: | Triage Stage: | Design decision needed | |
| Has patch: | no | Needs documentation: | no | 
| Needs tests: | no | Patch needs improvement: | no | 
| Easy pickings: | no | UI/UX: | no | 
Description
Advantage:  Greatly simplify a common usage with no breakage of old code, while making code more pythonic.
There should be a wildcard object to pass with keyword params to filter(), such that any keyword param is ignored which equals this wildcard object.  This should not break any existing code.
Examples:
def people_report(request, kw): 
for key in ('name', 'occupation'):
query_params = {}
if if key in kw and kw[key] != None:
query_params[key] = kw[key]
people = Person.objects.filter(query_params)
...
#COMPARED TO
def people_report(request, name=WILDCARD, occupation=WILDCARD):
people = Person.objects.filter(name=name, occupation=occupation)
...
#Implementation:
change django.db.models.manager.filter from:
def filter(self, *args, kwargs):
return self.get_query_set().filter(*args, kwargs)
TO:
def filter(self, *args, kwargs):
for key in kwargs:
if kwargs[key] == django.db.models.manager.WILDCARD:
del kwargs[key]
return self.get_query_set().filter(*args, kwargs)
Change History (2)
comment:1 by , 19 years ago
| Triage Stage: | Unreviewed → Design decision needed | 
|---|
comment:2 by , 18 years ago
| Resolution: | → wontfix | 
|---|---|
| Status: | new → closed | 
I don't think this is worth it. It's only one extra line of code (using a list comprehension) to do the check by hand. Any "wildcard" value we pick can then not be used as a value for that field.
Accepted for a Design Decision.
& for readability, here's the code provided by Justin wikified:
def people_report(request, **kw): for key in ('name', 'occupation'): query_params = {} if key in kw and kw[key] != None: query_params[key] = kw[key] people = Person.objects.filter(**query_params) ... #COMPARED TO def people_report(request, name=WILDCARD, occupation=WILDCARD): people = Person.objects.filter(name=name, occupation=occupation) ...Proposed patch:
#Implementation: change django.db.models.manager.filter from: def filter(self, *args, **kwargs): return self.get_query_set().filter(*args, **kwargs) TO: def filter(self, *args, **kwargs): for key in kwargs: if kwargs[key] == django.db.models.manager.WILDCARD: del kwargs[key] return self.get_query_set().filter(*args, **kwargs)