As you may be able to tell from my questions, I'm new to both python and django. I would like to allow dynamic filter specifications of query sets from my templates using **kwargs
. I'm thinking like a select box of a bunch of kwargs. For example:
<select id="filter">
<option value="physician__isnull=True">Unassigned patients</option>
</select>
Does django provide an elegant solution to this problem that I haven't come across yet?
I'm trying to solve this in a generic manner since I need to pass this filter to other views. For example, I need to pass a filter to a paginated patient list view, so the pagination knows what items it's working with. Another example is this filter would have to be passed to a patient detail page so you can iterate through the filtered list of patients with prev/next links.
Thanks a bunch, Pete
Update:
What I came up with was building a FilterSpecification
class:
class FilterSpec(object):
def __init__(self, name, *args):
super(FilterSpec, self).__init__()
self.name = name
self.filters = []
for filter in args:
self.add(filter)
def pickle(self):
return encrypt(pickle.dumps(self))
def add(self, f):
self.filters.append(f)
def kwargs(self):
kwargs = {}
for f in self.filters:
kwargs = f.kwarg(**kwargs)
return kwargs
def __unicode__(self):
return self.name
class Filter(object):
def __init__(self, key, value):
super(Filter, self).__init__()
self.filter_key = key
self.filter_value = value
def kwarg(self, **kwargs):
if self.filter_key != None:
kwargs[self.filter_key] = self.filter_value
return kwargs
I then can filter any type of model like this:
filterSpec = FilterSpec('Assigned', Filter('service__isnull', False)))
patients = Patient.objects.filter(**filterSpec.kwargs())
I pass these filterSpec objects from the client to server by serializing, compressing, applying some symmetric encryption, and url-safe base-64 encoding. The only downside is that you end up with URLs looking like this:
http://127.0.0.1:8000/hospitalists/assign_test/?filter=eJwBHQHi_iDiTrccFpHA4It7zvtNIW5nUdRAxdiT-cZStYhy0PHezZH2Q7zmJB-NGAdYY4Q60Tr_gT_Jjy_bXfB6iR8inrNOVkXKVvLz3SCVrCktGc4thePSNAKoBtJHkcuoaf9YJA5q9f_1i6uh45-6k7ZyXntRu5CVEsm0n1u5T1vdMwMnaNA8QzYk4ecsxJRSy6SMbUHIGhDiwHHj1UnQaOWtCSJEt2zVxaurMuCRFT2bOKlj5nHfXCBTUCh4u3aqZZjmSd2CGMXZ8Pn3QGBppWhZQZFztP_1qKJaqSVeTNnDWpehbMvqabpivtnFTxwszJQw9BMcCBNTpvJf3jUGarw_dJ89VX12LuxALsketkPbYhXzXNxTK1PiZBYqGfBbioaYkjo%3D
I would love to get some comments on this approach and hear other solutions.