从模板传递kwargs到视图?

1 投票
2 回答
1836 浏览
提问于 2025-04-15 13:33

从我的问题中你可能能看出来,我对Python和Django都很陌生。我想在我的模板中使用**kwargs来动态设置查询集的过滤条件。我的想法是像一个选择框,里面有一堆kwargs。比如:

  <select id="filter">
    <option value="physician__isnull=True">Unassigned patients</option>
  </select>

Django有没有提供一个优雅的解决方案,我还没发现呢?

我想以一种通用的方式来解决这个问题,因为我需要把这个过滤条件传递给其他视图。例如,我需要把过滤条件传递给一个分页的病人列表视图,这样分页才能知道它在处理哪些项目。另一个例子是,这个过滤条件还得传递给病人详情页面,这样你就可以通过上一个/下一个链接来浏览过滤后的病人列表。

非常感谢,Pete

更新:

我想到的办法是建立一个FilterSpecification类:

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

然后我可以像这样过滤任何类型的模型:

filterSpec = FilterSpec('Assigned', Filter('service__isnull', False)))
patients = Patient.objects.filter(**filterSpec.kwargs())

我通过序列化、压缩、应用一些对称加密和URL安全的base-64编码,把这些filterSpec对象从客户端传到服务器。唯一的缺点是,最终生成的URL看起来像这样:

http://127.0.0.1:8000/hospitalists/assign_test/?filter=eJwBHQHi_iDiTrccFpHA4It7zvtNIW5nUdRAxdiT-cZStYhy0PHezZH2Q7zmJB-NGAdYY4Q60Tr_gT_Jjy_bXfB6iR8inrNOVkXKVvLz3SCVrCktGc4thePSNAKoBtJHkcuoaf9YJA5q9f_1i6uh45-6k7ZyXntRu5CVEsm0n1u5T1vdMwMnaNA8QzYk4ecsxJRSy6SMbUHIGhDiwHHj1UnQaOWtCSJEt2zVxaurMuCRFT2bOKlj5nHfXCBTUCh4u3aqZZjmSd2CGMXZ8Pn3QGBppWhZQZFztP_1qKJaqSVeTNnDWpehbMvqabpivtnFTxwszJQw9BMcCBNTpvJf3jUGarw_dJ89VX12LuxALsketkPbYhXzXNxTK1PiZBYqGfBbioaYkjo%3D

我很想听听大家对这个方法的看法,也想知道其他的解决方案。

2 个回答

0

关于你的更新:FilterSpecs 不幸的是是 Django 中少数几个没有公开文档的部分之一。因此,不能保证它们会一直像现在这样正常工作。

另一种方法是使用 Alex Gaynor 的 django-filter,这个工具看起来设计得非常好。我打算在我的下一个项目中使用它。

1

与其冒着SQL注入的风险,不如给每个选择项分配一个值,然后让你的表单处理视图根据这个值来运行相应的查询。

把数据库查询的参数从页面传到视图中,这样做简直是在自找麻烦。Django这个框架就是为了避免这种情况而设计的。

撰写回答