分页和Django过滤器

时间:2019-03-26 16:21:31

标签: html django python-3.x listview django-generic-views

我正在尝试通过分页实现搜索功能。 我已经成功地使搜索工作或分页工作成功了。但是我不知道如何让他们两个同时工作。

这里是 .html ,通过将.html中的object_list切换为filter.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')

我不知道该如何修改但可以工作的部分是:我的模板

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
    https://stackoverflow.com/questions/22734695/next-and-before-links-for-a-django-paginated-query/22735278#22735278
    """
    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()

1 个答案:

答案 0 :(得分:1)

您可以通过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

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