分页和 django-filter

Pagination and django-filter

我正在尝试实现带分页的搜索功能。 我已经成功地设法让搜索工作或分页工作。但是我不知道如何让他们同时工作。

这里是.html,通过在.html中切换object_listfilter.qs,我可以切换在正确搜索或正确分页之间。 有人可以帮我修复代码,以便我可以一起工作吗?

{% extends 'base.html' %}
{% load widget_tweaks %}
{% load my_tags %}

{% block head %}
    <title> Overview</title>
{% endblock %}
{% block content %}
    <form method="get">
        <div class="jumbotron">
            <h4 style="margin-top: 0">Filter</h4>
            <div class="row">
                <div class="form-group col-sm-4 col-md-3">
                    {{ filter.form.name.label_tag }}
                    {% render_field filter.form.name class="form-control" %}
                </div>
                <div class="form-group col-sm-4 col-md-3">
                    {{ filter.form.city_location.label_tag }}
                    {% render_field filter.form.city_location class="form-control" %}
                </div>
            </div>
            <button type="submit" class="btn btn-primary">
                <span class="glyphicon glyphicon-search"></span> Search
            </button>
        </div>
    </form>


<table class="table table-bordered">
    <thead>
    <tr>
        <th>Name</th>
        <th>City Location</th>
    </tr>
    </thead>
    <tbody>
    {% for object in object_list %}
        <tr>
            <td>{{ object.name }}</td>
            <td>{{ object.city_location }}</td>

        </tr>
    {% empty %}
        <tr>
            <td colspan="5">No data</td>
        </tr>
    {% endfor %}
    </tbody>
</table>
<br>
<br>


<div id="footer">
    <div class="container text-center">
        <p class="text-muted credit" style="color:#fff">
            {% if is_paginated %}
                {% if page_obj.has_previous %}
                    <a href="?{% param_replace page=1 %}">First</a>
                    {% if page_obj.previous_page_number != 1 %}
                        <a href="?{% param_replace page=page_obj.previous_page_number %}">Previous</a>
                    {% endif %}
                {% endif %}
                Page {{ page_obj.number }} of {{ paginator.num_pages }}
                {% if page_obj.has_next %}
                    {% if page_obj.next_page_number != paginator.num_pages %}
                        <a href="?{% param_replace page=page_obj.next_page_number %}">Next</a>
                    {% endif %}
                    <a href="?{% param_replace page=paginator.num_pages %}">Last</a>
                {% endif %}

                <p>Objects {{ page_obj.start_index }}—{{ page_obj.end_index }}</p>
            {% endif %}
    </div>
</div>

{% endblock %}

这是我的模型

from django.db import models


# Create your models here.
class lab(models.Model):
    name = models.CharField(max_length=255)
    city_location = models.CharField(max_length=255)


    def __str__(self):
        return self.Lab_name

这是我的views.py

class labListView(LoginRequiredMixin, ListView):
    context_object_name = "Lab_folders"
    model = lab
    template_name = "researcher_view_app/Lab_overview.html"
    paginate_by = 20

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['filter'] = labOverviewFilter(self.request.GET, queryset=self.get_queryset())

        return context

这是我的filters.py

import django_filters


class labOverviewFilter(django_filters.FilterSet):
    Lab_name = django_filters.CharFilter(lookup_expr='icontains')
    Lab_city_location = django_filters.CharFilter(lookup_expr='icontains')

我不知道,我不知道如何修改但有效的部分是:我的 tempatetag

app_name/templatetags/my_tags.py

from django import template

register = template.Library()


@register.simple_tag(takes_context=True)
def param_replace(context, **kwargs):
    """
    Return encoded URL parameters that are the same as the current
    request's parameters, only with the specified GET parameters added or changed.

    It also removes any empty parameters to keep things neat,
    so you can remove a parm by setting it to ``""``.

    For example, if you're on the page ``/things/?with_frosting=true&page=5``,
    then

    <a href="/things/?{% param_replace page=3 %}">Page 3</a>

    would expand to

    <a href="/things/?with_frosting=true&page=3">Page 3</a>

    Based on
    
    """
    d = context['request'].GET.copy()
    for k, v in kwargs.items():
        d[k] = v
    for k in [k for k, v in d.items() if not v]:
        del d[k]
    return d.urlencode()

您可以在 get_queryset 方法中应用过滤器。像这样

class labListView(ListView):
    context_object_name = "Lab_folders"
    model = lab
    template_name = "researcher_view_app/Lab_overview.html"
    paginate_by = 20

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['filter'] = labOverviewFilter(self.request.GET, queryset=self.get_queryset())
        return context

    def get_queryset(self):
        qs = super().get_queryset()
        word = labOverviewFilter(self.request.GET, queryset=qs)
        return word.qs

分页逻辑在获取查询集后起作用。因此,向分页器提供过滤后的查询集。