对过滤器进行分页

Waz*_*azy 6 django django-filter django-pagination

我有一个过滤器,其中包含汽车品牌和型号的相关下拉列表。由于我不想在一页上显示所有内容,因此我添加了分页器。问题是过滤器工作正常,但无法在页面中保留

当过滤器处于活动状态时,网址看起来像

/cars/?manufacture=2&model=2 如果我转到下一页,我得到的只是/cars/?page=2

我想要类似的东西/cars/?manufacture=2&model=2?page=2

如果我打印{{ posts|length }}它确实会返回正在过滤的正确数量的项目,因此那里没有问题

我认为问题出在模板中的下一个和上一个按钮,因为它们不会传递下一页以外的任何参数。我如何将过滤器带入分页器。

看法

def allCarsView(request):

    model = Post
    
    myFilter = carFilter(request.GET, queryset=Post.objects.all())
    posts = myFilter.qs
    
    page = request.GET.get('page', 1)
    paginator = Paginator(posts.order_by('date_posted'), 2)
    page_obj = paginator.get_page(page)
    page_range = paginator.get_elided_page_range(number=page)
    
    context = {
        'posts':posts, 'myFilter':myFilter, 'page_range': page_range, 
        'page': page, 'paginator': paginator, 'page_obj': page_obj
    }
    return render(request, 'blog/cars.html', context)    
Run Code Online (Sandbox Code Playgroud)

html 分页器

<nav aria-label="Page navigation example " class="paginator">
<nav aria-label="Page navigation example " class="paginator">
    <ul class="pagination justify-content-center">
        <li class="page-item">
            {% if page_obj.has_previous %}
            <a class="page-link" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
            </a>
            {% else %}
        </li>

        <li class="page-item disabled">
            <a class="page-link" href="#" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
            </a>
        </li>
        {% endif %} {% for i in page_obj.paginator.page_range %} {% if page_obj.number == i %}
        <li class="page-item active" aria-current="page">
            <a class="page-link" href="#">{{ i }}</a>
        </li>
        {% elif i > page_obj.number|add:'-3' and i < page_obj.number|add:'3' %}
        <li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
        {% endif %} {% endfor %}

        <li class="page-item">
            {% if page_obj.has_next %}
            <a class="page-link" href="?page={{ page_obj.next_page_number }}" aria-label="Previous">
                <span aria-hidden="true">&raquo;</span>
            </a>
            {% else %}
        </li>

        <li class="page-item disabled">
            <a class="page-link" href="#" aria-label="Previous">
                <span aria-hidden="true">&raquo;</span>
            </a>
        </li>
        {% endif %}
    </ul>
</nav>
Run Code Online (Sandbox Code Playgroud)

更新:通过进行更多研究,我的问题似乎出在分页器中的网址,因为它们不携带任何参数。似乎没有最好的方法来做到这一点,并且我尝试过的解决方案没有产生任何结果。

更新:尝试使用这篇文章作为解决方案

查看(在之前的代码下添加) from django import template register = template.Library()

@register.simple_tag
def url_replace(request, field, value):

    dict_ = request.GET.copy()

    dict_[field] = value

    return dict_.urlencode()
Run Code Online (Sandbox Code Playgroud)

模板:

<a class="page-link" href="?{% url_replace request 'page' page_obj.next_page_number %}" aria-label="Previous">
Run Code Online (Sandbox Code Playgroud)

然后我得到错误

Invalid block tag on line 88: 'url_replace', expected 'elif', 'else' or 'endif'. Did you forget to register or load this tag?
Run Code Online (Sandbox Code Playgroud)

所以如果我在顶部添加

{% load url_replace %}
Run Code Online (Sandbox Code Playgroud)

抛出错误

'url_replace' is not a registered tag library

尝试能够从分页器中选择页码

            {% elif i > page_obj.number|add:'-3' and i < page_obj.number|add:'3' %}
            {% if page_obj.number > i  %}
                <li class="page-item"><a class="page-link" href="?{% querystring_replace request 'page' page_obj.previous_page_number %}">{{ i }}</a></li>    
            {% endif %}
            {% if page_obj.number < i  %}
                <li class="page-item"><a class="page-link" href="?{% querystring_replace request 'page' page_obj.next_page_number %}">{{ i }}</a></li>    
            {% endif %}
        {% endif %} {% endfor %}
Run Code Online (Sandbox Code Playgroud)

xyr*_*res 2

这可以使用自定义模板标签来完成,如本答案所示所示。然而,这个答案跳过了创建自定义标签的整个过程,所以让我向您展示如何做到这一点。

\n

Django 要求您的自定义标签保存在名为的文件夹中templatetags应用程序内部名为的文件夹中。因此,您的应用程序的文件夹结构必须如下所示:

\n
my-app/\n\xe2\x94\x9c\xe2\x94\x80 __ini__.py\n\xe2\x94\x9c\xe2\x94\x80 models.py\n\xe2\x94\x9c\xe2\x94\x80 views.py\n\xe2\x94\x9c\xe2\x94\x80 templatetags/\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 __init__.py\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 myapp_tags.py\n
Run Code Online (Sandbox Code Playgroud)\n

提示:您还可以创建一个专门用于保留自定义标签的新应用程序。这样,在不同的项目中重用它们就变得很容易。确保您的新应用程序已安装INSTALLED_APPS列表中。

\n

现在打开myapp_tags.py文件并在其中创建自定义标签:

\n
# myapp_tags.py\n\nfrom django import template\n\nregister = template.Library()\n\n@register.simple_tag\ndef querystring_replace(request, key, value):\n    """Replace the given `key` with the given `value`\n    in the request\'s querystring. The rest of the\n    querystring remains unchanged.\n    """\n    query_dict = request.GET.copy()\n    query_dict[key] = value\n    return query_dict.urlencode()\n
Run Code Online (Sandbox Code Playgroud)\n

要在模板中使用此标签,您需要加载包含标签的文件

\n
 <!-- load the file containing the tags -->\n{% load myapp_tags %}\n\n<!-- now you can use all the tags from myapp_tags -->\n{% querystring_replace request \'page\' page_obj.next_page_number %}\n
Run Code Online (Sandbox Code Playgroud)\n