使用 *args 和 **kwargs 在 Django 中进行动态查询
Dynamic querys in Django using *args and **kwargs
我正在尝试创建一个搜索表单,用户可以在其中选择几个选项来过滤搜索。我收到此错误:
sortedByScore() argument after * must be a sequence, not Q
views.py:
def results(request):
if request.method != "GET":
return HttpResponse("request method needs to be GET")
else:
bound_search_form = SearchForm(request.GET)
query = request.GET['query']
subject = request.GET['subject']
grade = request.GET['grade']
order_by = request.GET['order_by']
kwargs = {}
args = ()
if query:
query_word_list = query.split()
args = reduce(operator.or_, ((Q(title__contains=x) | Q(content__contains=x)) for x in query_word_list))
if subject != 'all':
kwargs["subject"] = subject
summaries_list = Summary.objects.sortedByScore(*args, **kwargs)
length = len(summaries_list)
# pagination
paginator = Paginator(summaries_list, 4)
# get page number from GET request
page_num = request.GET.get('page', 1)
# get summaries from paginator according to page number
try:
summaries = paginator.page(page_num)
except(EmptyPage, InvalidPage):
summaries = paginator.page(paginator.num_pages)
context_dict = {
'sumAmount': length,
'summaries': summaries,
'search_form': bound_search_form,
}
return render(request, 'results.html', context_dict)
我的自定义管理器的代码 sortedByScore:
class SummaryManager(models.Manager):
def sortedByScore(self, *args, **kwargs):
summaries = self.get_queryset().filter(*args, **kwargs)
return sorted(summaries, key=lambda summary: summary.get_score(),reverse=True)
您 sortedByScore(*args, **kwargs)
的第一个参数是一个 Q 对象:
args = reduce(operator.or_, ((Q(title__contains=x) | Q(content__contains=x)) for x in query_word_list))
您需要重新定义您的方法以传入不同的参数and/or在方法中执行reduce
。
args = reduce(operator.or_, ((Q(title__contains=x) | Q(content__contains=x)) for x in query_word_list))
reduce
将可迭代对象减少为单个对象,因此在这一行之后 args
不是可迭代对象。这将 args 减少为单个 Q
对象,OR
将 query_word_list
中的所有项目放在一起。如果你想使用 * 语法传递它,你需要将它包装在一个可迭代的对象中,即 args = (args,)
.
我正在尝试创建一个搜索表单,用户可以在其中选择几个选项来过滤搜索。我收到此错误:
sortedByScore() argument after * must be a sequence, not Q
views.py:
def results(request):
if request.method != "GET":
return HttpResponse("request method needs to be GET")
else:
bound_search_form = SearchForm(request.GET)
query = request.GET['query']
subject = request.GET['subject']
grade = request.GET['grade']
order_by = request.GET['order_by']
kwargs = {}
args = ()
if query:
query_word_list = query.split()
args = reduce(operator.or_, ((Q(title__contains=x) | Q(content__contains=x)) for x in query_word_list))
if subject != 'all':
kwargs["subject"] = subject
summaries_list = Summary.objects.sortedByScore(*args, **kwargs)
length = len(summaries_list)
# pagination
paginator = Paginator(summaries_list, 4)
# get page number from GET request
page_num = request.GET.get('page', 1)
# get summaries from paginator according to page number
try:
summaries = paginator.page(page_num)
except(EmptyPage, InvalidPage):
summaries = paginator.page(paginator.num_pages)
context_dict = {
'sumAmount': length,
'summaries': summaries,
'search_form': bound_search_form,
}
return render(request, 'results.html', context_dict)
我的自定义管理器的代码 sortedByScore:
class SummaryManager(models.Manager):
def sortedByScore(self, *args, **kwargs):
summaries = self.get_queryset().filter(*args, **kwargs)
return sorted(summaries, key=lambda summary: summary.get_score(),reverse=True)
您 sortedByScore(*args, **kwargs)
的第一个参数是一个 Q 对象:
args = reduce(operator.or_, ((Q(title__contains=x) | Q(content__contains=x)) for x in query_word_list))
您需要重新定义您的方法以传入不同的参数and/or在方法中执行reduce
。
args = reduce(operator.or_, ((Q(title__contains=x) | Q(content__contains=x)) for x in query_word_list))
reduce
将可迭代对象减少为单个对象,因此在这一行之后 args
不是可迭代对象。这将 args 减少为单个 Q
对象,OR
将 query_word_list
中的所有项目放在一起。如果你想使用 * 语法传递它,你需要将它包装在一个可迭代的对象中,即 args = (args,)
.