【问题标题】:Passing kwargs from template to view?将 kwargs 从模板传递到视图?
【发布时间】:2009-08-13 01:09:18
【问题描述】:

从我的问题中您可能可以看出,我对 python 和 django 都是新手。我想允许使用**kwargs 从我的模板中对查询集进行动态过滤规范。我想的是一堆 kwargs 的选择框。例如:

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

django 是否为这个我还没有遇到过的问题提供了一个优雅的解决方案?

我正在尝试以通用方式解决此问题,因为我需要将此过滤器传递给其他视图。例如,我需要将过滤器传递给分页的患者列表视图,以便分页知道它正在处理哪些项目。另一个例子是这个过滤器必须被传递到患者详细信息页面,这样您就可以使用上一个/下一个链接遍历过滤后的患者列表。

非常感谢,皮特

更新:

我想出的是建立一个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-safe 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

我很想获得一些关于这种方法的 cmets 并听取其他解决方案。

【问题讨论】:

  • 看起来是打开安全漏洞的好方法,人们可以在您的数据库上运行自定义查询。
  • 如果您维护一个允许键的列表,例如医师* 或名字*,我看不出这会导致什么问题。

标签: python django


【解决方案1】:

与其面对 SQL 注入的可怕危险,不如直接为每个选择选项分配一个值,并让您的表单处理视图根据该值运行选定的查询。

将数据库查询的参数从页面传递到视图只是自找麻烦。 Django 就是为了避免这种事情而构建的。

【讨论】:

  • 在多个视图中将需要此过滤器。我正在尝试以通用方式解决此问题。
【解决方案2】:

关于您的更新:不幸的是,FilterSpecs 是 Django 中缺少公共文档的(罕见的)部分之一。因此,无法保证他们会继续工作。

另一种方法是使用 Alex Gaynor 的 django-filter,它看起来经过深思熟虑。我将在下一个项目中使用它们。

【讨论】:

  • 谢谢 piquadrat。您是否知道 django-filter 是否提供任何安全措施以确保不允许未指定的过滤器?
  • 不幸的是,Alex 的实现安全性为零。我可以选择任何我想要的自定义过滤器。
猜你喜欢
  • 2015-09-18
  • 2018-03-23
  • 2015-07-07
  • 2018-02-10
  • 1970-01-01
  • 2017-04-26
  • 2016-09-28
  • 2020-03-19
  • 2019-02-16
相关资源
最近更新 更多