【问题标题】:Chaining filters链接过滤器
【发布时间】:2017-02-10 13:34:43
【问题描述】:

Django 1.10.1

在一个页面上我准备了很多控件。其中一些被组织为动态变化的表单集。所以,我什至不知道他们中有多少人在场。

我需要一个带有 AND、OR 和 NOT 逻辑运算的链式过滤器。

例如,我需要这样的东西:

Entry.objects.filter(headline__startswith='What').exclude(pub_date__gte=datetime.date.today()).filter(pub_date__gte=datetime(2005, 1, 30)).filter(Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))

过滤器的数量再次发生变化。

我正计划这样做:遍历 request.POST 并根据十几个条件准备一个字符串。相同的字符串:

"Entry.objects.filter(headline__startswith='What').exclude(pub_date__gte=datetime.date.today()).filter(pub_date__gte=datetime(2005, 1, 30)).filter(Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))"

所以,字符串是正确的。但我不能让它与 exec() 一起工作。 我在这里问:为什么它不起作用。答案是:不行,直接运行Python代码。

我可以构建类似的东西:

entries = Entry.objects.filter( **kwargs )

但这只是一个过滤器。我无法想象如何链接这样的过滤器。

你能帮我吗&

【问题讨论】:

  • 我想知道您的POST 请求是什么样的。

标签: django django-orm


【解决方案1】:

您可以将查询集链接到多行 - 根据视图逻辑添加额外的查询。这些查询集在创建时不会执行,只有在调用时才会执行。

我不确定这是否是“最好的”或最 Pythonic 的方式,但这样的方式对我来说非常有效。这是使用 Django Rest Framework 辅助方法,但它应该适用于:

def get(self, request, format=None, *args, **kwargs):
        name = request.GET.get('name', None)
        location = request.GET.get('location', None)
        id = request.GET.get('id', None)

        results = Model.objects.all().order_by('-created')  # this would be the default with no filters on it
        results = results.filter(name__iexact=name) if name else results
        results = results.filter(location__icontains=location) if location else results
        results = results.filter(id__exact=id) if id else results

        # process/serialize/send response

不知道你会得到哪些参数可能会很棘手,但一个想法可能是循环你的 kwargs 并在循环中遵循相同的模式 - 这是一个刺(注意我没有测试过):

def get(self, request, format=None, *args, **kwargs):

        results = Model.objects.all().order_by('-created')  # this would be the default
        for param, value in kwargs.items():
             results = results.filter(***need to convert param to orm field***= value)

【讨论】:

  • 工作。但是链接 OR 运算符仍然存在问题。我需要 Article.objects.filter( Q(title__icontains="table") | Q(title__icontains="helm") ) 之类的东西。好吧,这是个问题——语法是 filter(**kwargs)。但是如何传递那个“我”呢?
  • 你能遵循类似的模式吗? stackoverflow.com/a/852481/4396787
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-06
相关资源
最近更新 更多