简体   繁体   English

将kwargs从模板传递到视图?

[英]Passing kwargs from template to view?

As you may be able to tell from my questions, I'm new to both python and django. 正如您可能从我的问题中看出来的那样,我是python和django的新手。 I would like to allow dynamic filter specifications of query sets from my templates using **kwargs . 我想使用**kwargs允许模板中的查询集动态过滤器规范。 I'm thinking like a select box of a bunch of kwargs. 我在想像是一堆kwarg的选择框。 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? django是否可以为我还没有遇到的这个问题提供一个优雅的解决方案?

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: FilterSpecification是建立一个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

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. 我通过序列化,压缩,应用一些对称加密和url-safe base-64编码,将这些filterSpec对象从客户端传递到服务器。 The only downside is that you end up with URLs looking like this: 唯一的缺点是您最终得到的URL如下所示:

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. 与其面对SQL注入的可怕危险,不如不给每个select选项分配一个值,并让您的表单处理视图基于该值运行所选查询,就可以了。

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. Django的创建是为了避免这种情况。

Concerning your update: FilterSpecs are unfortunately one of those (rare) pieces of Django that lack public documentation. 关于您的更新:很遗憾,FilterSpecs是Django这些(少有的)缺少公共文档的文件之一。 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. 另一种方法是使用Alex Gaynor的django过滤器 ,该过滤器看起来经过深思熟虑。 I'll be using them for my next project. 我将在下一个项目中使用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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