Am I dynamic filtering correctly in Django? I needed a way to get URL parameters and put them and their values into a query set's .filter() if they exist. After a day of piecing together information from the Interwebs, I have a working solution to my problem. However, is it the best way to do this? I feel it can be improved or streamlined, but my tiny brain is failing me:

In utilities.py:

def get_filters(url, allowed):
    query = parse.urlsplit(url).query
    pack = dict(parse.parse_qsl(query))
    translated = {}

    for pk, pv in pack.items():
        for ak, av in allowed.items():
            if pk == ak:
                translated[av] = pv

    return translated


In views.py:

from utilities import get_filters

people = Person.objects.all()
url = request.get_full_path()

allowed_filters = {
    'location': 'person_location',
    'role': 'person_role',
}

filters = get_filters(url, allowed_filters)

if filters:
    filtered_query = people.filter(**filters)
else:
    filtered_query = people

if ('search' in request.GET) and request.GET['search'].strip():
    query_string = request.GET['search']
    query_search = get_query(query_string, ['person_first_name', 'person_last_name'])
    query_results = filtered_query.filter(query_search)
else:
    query_results = filtered_query


It does everything I need it to: if a URL parameter is in the allowed list, it takes that parameter and value, packs it into a dictionary, and shoves it into filter() to be unpacked by the interpreter.

This way whenever I want to add a new filter, I just add it in the allowed list and I don't have to touch anything else. I did it this way so I could use an alias like special_id=3 in the URL to target a relationship like person__special__special_id=3 without the URL getting cluttered like the Django admin side does.

Any suggestions for improving this?
You can change the first method to

def get_filters(url, allowed):
    query = parse.urlsplit(url).query
    pack = dict(parse.parse_qsl(query))
    translated = {}

    for pk, pv in pack.items():
        if pk in allowed:
            translated[allowed[pk]] = pv

    return translated


Remove this condition, it's useless.

if filters:
    filtered_query = people.filter(**filters)
else:
    filtered_query = people


and just use 

filtered_query = people.filter(**filters)


Maybe add search to the allowed filters? and improve the method to handle multiple values for a specific key.

allowed_filters = {
    'location': 'person_location',
    'role': 'person_role',
    'search': ['person_first_name', 'person_last_name']
}

```