Opened 8 years ago

Closed 8 years ago

#3746 closed (wontfix)

Add a wildcard object for use in objects.filter queries.

Reported by: justin.vanwinkle@… Owned by: adrian
Component: Database layer (models, ORM) Version: master
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: UI/UX:

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 Changed 8 years ago by Simon G. <dev@…>

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed

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)

comment:2 Changed 8 years ago by mtredinnick

  • Resolution set to wontfix
  • Status changed from new to 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.

Note: See TracTickets for help on using tickets.
Back to Top