在我的viewSet中,我正在进行查询,
queryset= Books.objects.all();
现在从ajax调用我从UI获取我的过滤器值,即auther的年龄,性别等。总共将有5个过滤器。
现在我遇到的问题是如何向查询添加过滤器(只有那些具有任何值的过滤器)。
我尝试的是检查了单个过滤器值并进行了查询,但这样就失败了,就像用户删除过滤器值或添加多个过滤器一样。 有什么更好的建议如何实现这个目标?
答案 0 :(得分:9)
您尚未显示任何代码,因此您尚未真正解释问题所在:
从查询集Book.objects.all()
开始。对于每个过滤器,检查request.POST
中是否存在过滤器的值,如果是,则过滤查询集。 Django查询集是惰性的,因此只会评估最终的查询集。
queryset = Book.objects.all()
if request.POST.get('age'):
queryset = queryset.filter(author__age=request.POST['age'])
if request.POST.get('gender'):
queryset = queryset.filter(author__gender=request.POST['gender'])
...
答案 1 :(得分:8)
这是一个更通用的。如果它们作为GET
参数传递,它将对您的查询集应用过滤器。如果您正在进行POST
调用,只需更改代码中的名称即可。
import operator
def your_view(self, request, *args, **kwargs):
# Here you list all your filter names
filter_names = ('filter_one', 'filter_two', 'another_one', )
queryset = Books.objects.all();
filter_clauses = [Q(filter=request.GET[filter])
for filter in filter_names
if request.GET.get(filter)]
if filter_clauses:
queryset = queryset.filter(reduce(operator.and_, filter_clauses))
# rest of your view
请注意,您可以在过滤器的名称中使用查找表达式。例如,如果您要过滤价格低于或等于过滤器中指定价格的图书,则可以使用price__lte
作为过滤器名称。
答案 2 :(得分:4)
你可以简单地获取request.GET内容作为dict(确保将值转换为字符串或所需类型,因为它们是默认列表,即:dict(request.GET)
会给你类似{{{ 1}}。
一旦确定您拥有与模型字段匹配的密钥字典,您就可以执行以下操作:
{u'a': [u'val']}
答案 3 :(得分:2)
也许django-filter有助于简化其他人提供的解决方案?
类似的东西:
class BookFilter(django_filters.FilterSet):
class Meta:
model = Book
fields = ['author__age', 'author__gender', ...]
然后视图如下:
def book_list(request):
f = BookFilter(request.GET, queryset=Book.objects.all())
return render_to_response('my_app/template.html', {'filter': f})
有关详细信息,请参阅documentation。
答案 4 :(得分:1)
这对我有用,我将Alex Morozov的回答与Dima answer
合并了import operator
def your_view(self, request, *args, **kwargs):
# Here you list all your filter names
filter_names = ('filter_one', 'filter_two', 'another_one', )
queryset = Books.objects.all();
filter_clauses = [Q(**{filter: request.GET[filter]})
for filter in filter_names
if request.GET.get(filter)]
if filter_clauses:
queryset = queryset.filter(reduce(operator.and_, filter_clauses))
# rest of your view
答案 5 :(得分:0)
您可以做类似的事情
class BooksAPI(viewsets.ModelViewSet):
queryset = Books.objects.none()
def get_queryset(self):
argumentos = {}
if self.request.query_params.get('age'):
argumentos['age'] = self.request.query_params.get('age')
if self.request.query_params.get('gender'):
argumentos['gender'] = self.request.query_params.get('gender')
if len(argumentos) > 0:
books = Books.objects.filter(**argumentos)
else:
books = Books.objects.all()
return books