繁体   English   中英

Django中使用* args和** kwargs的动态查询

[英]Dynamic querys in Django using *args and **kwargs

我正在尝试创建一个搜索表单,用户可以从中选择一些选项来过滤搜索。 我收到此错误:

*之后的sortedByScore()参数必须是序列,而不是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)
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(*args, **kwargs)第一个参数是Q对象:

args = reduce(operator.or_, ((Q(title__contains=x) | Q(content__contains=x)) for x in query_word_list))

您将需要重新定义方法以传入不同的参数和/或在方法内部执行reduce

暂无
暂无

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

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