【问题标题】:Is there any way to use Pagination with django-filter?有没有办法将分页与 django-filter 一起使用?
【发布时间】:2020-07-17 17:14:26
【问题描述】:

每当我点击下一页的链接(这是一个获取请求)时,过滤器都会被绕过,我会得到整个列表的相应页面(没有过滤器)。例如,如果我在过滤列表的第 1 页并单击下一步,我将在整个未过滤列表的第 2 页着陆。 在models.py中,

class Person(models.Model):
    name = models.CharField(max_length=50, unique=True)
    gender = models.CharField(max_length=7, choices=GENDER_CHOICES)
    category = models.CharField(max_length=20, choices=get_all_category_choices())

在filters.py中,

import django_filters

from .models import Person

class PersonFilter(django_filters.FilterSet):

    class Meta:
        model = Person
        fields = [
            'name',
            'gender',
            'category',
        ]

在views.py中,

def show_all_persons_page(request):
    context = {}

    filtered_person_list = PersonFilter(
        request.GET,
        queryset=Person.objects.all()
    )

    context['filtered_person_list'] = filtered_person_list

    paginated_filtered_person_list = Paginator(filtered_person_list.qs, 3)
    page_number = request.GET.get('page')
    person_page_obj = paginated_filtered_person_list.get_page(page_number)

    context['person_page_obj'] = person_page_obj

    return render(request, 'app1/show_all_persons_page.html', context)

在 app1/show_all_persons_page.html,

<form method="get">
    {{ filtered_person_list.form.as_p }}
    <button type="submit">Search</button>
</form>

{% for person in person_page_obj %}
    <img src="{{ person.picture.url }}" width="240">
    <h2>
        {{person.name}}
        <br>
        {{person.gender}}
        <br>
        {{person.category}}
        <br>
    </h2>
    <br>
{% endfor %}

<div class="pagination">
    <span class="step-links">
        {% if person_page_obj.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ person_page_obj.previous_page_number }}">previous</a>
        {% endif %}

        <span class="current">
            Page {{ person_page_obj.number }} of {{ person_page_obj.paginator.num_pages }}.
        </span>

        {% if person_page_obj.has_next %}
            <a href="?page={{ person_page_obj.next_page_number }}">next</a>
            <a href="?page={{ person_page_obj.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
</div>

【问题讨论】:

  • 您需要保留旧的查询字符串 (?name=x&gender=y&category=z),添加 &page=num。在视图代码中构建页面列表及其 url 可能更容易。
  • 您能详细说明一下吗?我在任何地方都没有看到。
  • 以下是对该特定问题的一些回复。 stackoverflow.com/questions/2047622/…

标签: python django django-models pagination django-filter


【解决方案1】:

解决了。概念来自https://simpleisbetterthancomplex.com/snippet/2016/08/22/dealing-with-querystring-parameters.html。为了保留当前的 ​​url 参数,我们必须定义一个自定义模板标签。在 app1 下创建一个名为 templatetags 的新目录。在该目录中创建一个__init__.py。创建另一个 .py 文件,比如 app1_extras。在 app1_extras 中,定义一个自定义模板标签,如下所示。 app1/templatetags/app1_extras.py,

from django import template

register = template.Library()

@register.simple_tag
def relative_url(value, field_name, urlencode=None):
    url = '?{}={}'.format(field_name, value)
    if urlencode:
        querystring = urlencode.split('&')
        filtered_querystring = filter(lambda p: p.split('=')[0] != field_name, querystring)
        encoded_querystring = '&'.join(filtered_querystring)
        url = '{}&{}'.format(url, encoded_querystring)
    return url

这将获取我们当前的 url 并确保参数与页码一起到位。 field_name 是字符串“page”,value 是将从模板传递的页码。 urlencode 将我们当前的 url 表示为一个字符串。 在 app1/show_all_persons.html,

{% load app1_extras %}

<form method="get">
    {{ filtered_person_list.form.as_p }}
    <button type="submit">Search</button>
</form>

{% for person in person_page_obj %}
    <img src="{{ person.picture.url }}" width="240">
    <h2>
        {{person.name}}
        <br>
        {{person.gender}}
        <br>
        {{person.category}}
        <br>
    </h2>
    <br>
{% endfor %}

<div class="pagination">
    <span class="step-links">
        {% if person_page_obj.has_previous %}
            <a href="{% relative_url 1 'page' request.GET.urlencode %}">&laquo; first</a>
            <a href="{% relative_url person_page_obj.previous_page_number 'page' request.GET.urlencode %}">previous</a>
        {% endif %}

        <span class="current">
            Page {{ person_page_obj.number }} of {{ person_page_obj.paginator.num_pages }}.
        </span>

        {% if person_page_obj.has_next %}
            <a href="{% relative_url person_page_obj.next_page_number 'page' request.GET.urlencode %}">next</a>
            <a href="{% relative_url person_page_obj.paginator.num_pages 'page' request.GET.urlencode %}">last &raquo;</a>
        {% endif %}
    </span>
</div>

{% load app1_extras %} 将加载我们新的自定义模板标签。现在将 relative_url 函数传递给我们页面链接的 href。参数按照 request.GET.urlencode 包含我们当前 url 的顺序传递,并将传递给 urlencode 参数。

【讨论】:

    猜你喜欢
    • 2018-03-15
    • 2016-11-01
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多