简体   繁体   中英

Passing kwargs from template to view?

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.

Rather than face the horrible dangers of SQL injection, why not just assign a value to each select option and have your form-handling view run the selected query based on the value.

Passing the parameters for a DB query from page to view is just asking for disaster. Django is built to avoid this sort of thing.

Concerning your update: FilterSpecs are unfortunately one of those (rare) pieces of Django that lack public documentation. As such, there is no guarantee that they will keep working as they do.

Another approach would be to use Alex Gaynor's django-filter which look really well thought out. I'll be using them for my next project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM