【问题标题】:Filtering and Ordering based on multiple request.GET parameters基于多个 request.GET 参数的过滤和排序
【发布时间】:2016-08-20 10:27:44
【问题描述】:

我目前正忙于寻找解决问题的方法。所以我有一个这样的网址:

https://www.domain.com/forum/topic/

在我的模板视图中,我有一个表单和一个负责搜索帖子的输入:

<form method="GET" action="">
    <div class="input-group">
        <input type="text" name="q" placeholder="Search..." value="{{ request.GET.q }}" class="form-control">
        <span class="input-group-btn">
            <input class="btn btn-secondary" type="submit" value="Search">
        </span>
    </div>
</form>

在我的 Views.py 中,搜索行为如下:

def discussion(request, discussion):
    topics_list = Topic.objects.all().filter(discussion__url=discussion)
    discussion = Discussion.objects.get(url=discussion)

    search_query = request.GET.get('q')

    if search_query:
        topics_list = topics_list.filter(
            Q(title__icontains=search_query) |
            Q(user__username__icontains=search_query)
            )

    paginator = Paginator(topics_list, 10)
    page = request.GET.get('page')
    try:
        topics = paginator.page(page)
    except PageNotAnInteger:
        topics = paginator.page(1)
    except EmptyPage:
        topics = paginator.page(paginator.num_pages)


    context = {'topics': topics, 'discussion': discussion,}
    return render(request, 'forum/forum_show_posts.html', context)

现在,当我运行搜索时,它工作正常,它实际上根据我的查询过滤了对象,从而使 url 显示为:

https://www.domain.com/forum/topic/?q=test

现在我想为我的对象处理订单,因此我将讨论视图修改为:

def discussion(request, discussion):
    topics_list = Topic.objects.all().filter(discussion__url=discussion)
    discussion = Discussion.objects.get(url=discussion)

    search_query = request.GET.get('q')
    sort_query = request.GET.get('sort')

    if search_query:
        topics_list = topics_list.filter(
            Q(title__icontains=search_query) |
            Q(user__username__icontains=search_query)
            )

    elif sort_query:
        if sort_query == "newest":
            topics_list = topics_list.order_by('-timestamp')
        if sort_query == "oldest":
            topics_list = topics_list.order_by('timestamp')
        if sort_query == "name":
            topics_list = topics_list.order_by('title')

        # sort_query = sort_query.title()

    paginator = Paginator(topics_list, 10)
    page = request.GET.get('page')
    try:
        topics = paginator.page(page)
    except PageNotAnInteger:
        topics = paginator.page(1)
    except EmptyPage:
        topics = paginator.page(paginator.num_pages)


    context = {'topics': topics, 'discussion': discussion, 'sort_value':sort_query,}
    return render(request, 'forum/forum_show_posts.html', context)

和我的模板为每种订购方法提供相应的链接:

<div class="dropdown-menu">
    <a class="dropdown-item disabled" href="#">Sort...</a>
        <form method="GET" action="">
            <div class="input-group">
                <button class="dropdown-item" type="submit" name="sort" value="newest">Newest</button>
                <button class="dropdown-item" type="submit" name="sort" value="oldest">Oldest</button>
                <button class="dropdown-item" type="submit" name="sort" value="views">Views</button>
                <button class="dropdown-item" type="submit" name="sort" value="comments">Comments</button>
                <button class="dropdown-item" type="submit" name="sort" value="replies">Replies</button>
                <button class="dropdown-item" type="submit" name="sort" value="name">Name</button>
            </div>
        </form>
</div>

现在,当我实际选择按最新或最旧排序时,它会对它们进行排序,使 url 显示为:

https://www.domain.com/forum/topic/?sort=newest

我的问题是,假设我想搜索“测试”来制作 URL

https://www.domain.com/forum/topic/?q=test

但是当我想用搜索排序时,它会被覆盖,而是只显示所有帖子,以及我选择排序的内容。即使已经存在搜索,我如何对其进行排序,如果没有搜索仍然对其进行排序。

https://www.domain.com/forum/topic/?q=testhttps://www.domain.com/forum/topic/?q=test&amp;sort=newest 所以它显示了带有查询'test'的最新帖子列表。

【问题讨论】:

  • q 参数存储在排序表单的隐藏输入中怎么样?
  • @JordanJambazov 你能详细说明一下吗?
  • 部分问题是提交排序时,q 参数消失。原因是排序表单有action=""。如果您将查询存储在排序表单的隐藏输入中,例如&lt;input type="hidden" name="q" value="{{ request.GET.q }}"&gt;,您还将在搜索期间保留查询。
  • 我这样做了,但它隐藏了搜索栏,它仍然没有保留 q

标签: python django sorting


【解决方案1】:

您需要跟踪您的 GET 参数,将您的视图更新为:

def discussion(request, discussion): # <<- view name and var name both are same which might cause issues
    search_query = request.GET.get('q', '')
    sort = request.GET.get('sort', '')
    direction = request.GET.get('dir', 'asc')
    if direction not in ['asc', 'desc']:
        direction = 'asc'

    topics_list = Topic.objects.all().filter(discussion__url=discussion)
    discussion = Discussion.objects.get(url=discussion)

    if search_query:
        topics_list = topics_list.filter(
            Q(title__icontains=search_query) |
            Q(user__username__icontains=search_query)
        )

    if sort:
        order_by = '{0}{1}'.format('-' if direction == 'desc' else '', sort)
        topics_list = topics_list.order_by(order_by)

    # rest of code
    # pass search_query, sort and direction in context
    context = {
        'topics': topics,
        'discussion': discussion,
        'sort': sort,
        'direction': direction,
        'search_query': search_query,
    }

    return render(request, 'forum/forum_show_posts.html', context)

现在在模板中以两种形式跟踪这些参数:

搜索表格:

<form method="GET" action="">
    <div class="input-group">
        <input type="text" name="q" placeholder="Search..." value="{{ search_query }}" class="form-control">
        <span class="input-group-btn">
            <input class="btn btn-secondary" type="submit" value="Search">
        </span>
    </div>
    <input type="hidden" name="sort" value="{{ sort }}" />
    <input type="hidden" name="direction" value="{{ direction }}" />
</form>

排序形式:

<div class="dropdown-menu">
    <a class="dropdown-item disabled" href="#">Sort...</a>
        <form method="GET" action="">
            <div class="input-group">
                <button class="dropdown-item" type="submit" name="sort" value="newest">Newest</button>
                <button class="dropdown-item" type="submit" name="sort" value="oldest">Oldest</button>
               <button class="dropdown-item" type="submit" name="sort" value="views">Views</button>
               <button class="dropdown-item" type="submit" name="sort" value="comments">Comments</button>
               <button class="dropdown-item" type="submit" name="sort" value="replies">Replies</button>
               <button class="dropdown-item" type="submit" name="sort" value="name">Name</button>
            </div>

            <input type="hidden" name="search_query" value="{{ search_query }}" />
            <input type="hidden" name="direction" value="{{ direction }}" />

        </form>
</div>

【讨论】:

  • 无论从 asc 还是 desc 更改,似乎都没有对帖子进行排序,但是它确实搜索具有指定文本的帖子,但它仍然显示我的旧查询。
  • 谢谢!我使用了一些你给我的代码,特别是 GET 参数的保留方法,并设法解决了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-23
  • 2019-10-28
  • 1970-01-01
  • 2018-07-27
相关资源
最近更新 更多