分页和Django过滤器 [英] Pagination and django-filter

查看:62
本文介绍了分页和Django过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to implement a search feature with pagination. I have successfully either managed to get the search to work or the pagination to work. But I cannot figure out how to get both of them working together at the same time.

这是 .html ,通过将.html中的 object_list 切换为 filter.qs ,我可以在正确搜索或分页正确.有人可以帮我修复代码,以便让我俩一起工作吗?

Here is the .html, by switching object_list to filter.qs in the .html, I can switch between either searching correctly or pagination correctly. Can someone help me fix the code so that I can have both working together ?

{% 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')

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

And the part which I have no idea about, that I do not know how to modify but works is: my tempatetag

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()

推荐答案

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

You can apply filter in get_queryset method. Like this

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后起作用.因此,将过滤后的查询集提供给分页器.

pagination logic works after getting queryset. So provide filtered queryset to paginator.

这篇关于分页和Django过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆