Пагинация и джанго-фильтр - PullRequest
0 голосов
/ 26 марта 2019

Я пытаюсь реализовать функцию поиска с нумерацией страниц.Мне удалось либо заставить поиск работать, либо разбить на страницы.Но я не могу понять, как заставить их обоих работать вместе одновременно.

Вот .html , переключив object_list на filter.qs в .html,Я могу переключаться между поиском правильно или нумерацией страниц.Может кто-нибудь помочь мне исправить код, чтобы я мог работать вместе?

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

И та часть, о которой я понятия не имею, о которой я не знаюзнать, как изменить, но работает это: мой шаблон

имя_приложения / 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 Ответ

1 голос
/ 26 марта 2019

Вы можете применить фильтр в методе 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

логика разбиения на страницы работает после получения набора запросов. Поэтому предоставьте отфильтрованный набор запросов для paginator.

...