链接过滤器
Chaining filters
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 )
但这只是一个过滤器。我无法想象如何链接这样的过滤器。
你能帮我吗&
您可以在多行上链接一个查询集 - 根据视图逻辑添加额外的查询。这些查询集不会在创建时执行,仅在调用时执行。
我不确定它是 "best" 还是最像 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)
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 )
但这只是一个过滤器。我无法想象如何链接这样的过滤器。
你能帮我吗&
您可以在多行上链接一个查询集 - 根据视图逻辑添加额外的查询。这些查询集不会在创建时执行,仅在调用时执行。
我不确定它是 "best" 还是最像 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)