分页和Django过滤器 [英] Pagination and django-filter
问题描述
我正在尝试通过分页实现搜索功能.我已经成功地使搜索工作或分页工作成功了.但是我不知道如何让他们两个同时工作.
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屋!