Django Pagination - перегруппировать и показать группу раз на странице?

В настоящее время я перегруппировываю некоторые данные, а затем отображаю эти данные в столбцах, а также использую разбиение на страницы. Однако из-за упорядочения исходных данных бывают случаи, когда в столбце 1 есть 1 запись, но на самом деле всего 5 или 6 записей, но они будут на разных страницах, возможно ли перегруппировать данные так, чтобы количество элементов на странице берется по количеству сгруппированных элементов?

Я думал о сортировке данных перед их публикацией на странице, но тогда будет отображаться только один столбец типов на странице (может быть 1 или n типов/столбцов, которые я хотел бы иметь на одной странице)

примечание: приведенные ниже образцы данных не являются фактическими данными,

Надеюсь, приведенный ниже пример прояснит ситуацию.

исходные данные:

  ID       Type      Item
----------------------------
  9        Fruit     Apple    
  15       Meat      Beef    
  18       Fruit     Lemon    
  99       Fruit     Orange   
  9        Fruit     Grape    
  77       Meat      Chicken    

Постраничный и сгруппированный текущий вывод данных

 Meat          Fruit
-------       -------
 Beef          Apple
               Lemon

page 1 of 2 (3 items per page)

 Meat          Fruit
-------       -------
 Chicken       Orange
               Grape

page 2 of 2 (3 items per page)

Желаемый результат

 Meat          Fruit
-------       -------
 Beef          Apple
Chicken        Lemon
               Orange

page 1 of 2 (3 items per group per page)

 Meat          Fruit
-------       -------
               Grape

page 2 of 2 (3 items per group per page)

Это мой текущий шаблон:

{% include 'search/page_nav.html' %}
{% with results.object_list as results_list %}
    {% regroup results_list|dictsort:"model_name" by model_name as grouped_objects %}
    {% for ct in grouped_objects %}
        <div class="col-4">
            <h3 class="text-capitalize">{{ ct.grouper }}'s</h3>
            {% for result in ct.list %}
            <div class="col-12 results">
                <div class="pt-4 border-bottom">
                    <a class="page-url h4 text-primary" href="{{ result.object.get_absolute_url }}">{{ result.object.get_search_title }}</a>
                    <p class="page-description mt-1 text-muted"> {{ result.object.get_search_text|safe }}</p>
                </div>
            </div>
            {% endfor %}
        </div>
    {% empty %}
        <p class="lead">Although I am a guru, I am lacking sentience. One must ask a specific question to recieve a specific answer.</p>
    {% endfor %}
{% endwith %}
{% include 'search/page_nav.html' %}

и шаблон пагинации:

{% if results.has_previous or results.has_next %}
    <nav class="col-12" aria-label="Page navigation">
        <ul class="pagination mb-2">
            <li class="page-item {% if not results.has_previous %} disabled {% endif %}"><a class="page-link" href="{% if results.has_previous %}?q={{ query }}&amp;page={{ results.previous_page_number }}{% endif %}">Previous</a>
            {% if results.number|add:'-5' > 1 %}
                <li class="page-item active}"><a class="page-link" href="?q={{ query }}&amp;page={{ results.number|add:'-5' }}">&hellip;</a></li>
            {% endif %}
            {% for i in results.paginator.page_range %}
                {% if results.number == i %}
                <li class="page-item active"><a class="page-link" href="?q={{ query }}&amp;page={{ i }}">{{ i }}</a></li>
                {% elif i > results.number|add:'-6' and i < results.number|add:'6' %}
                <li class="page-item"><a class="page-link" href="?q={{ query }}&amp;page={{ i }}">{{ i }}</a></li>
                {% endif %}
            {% endfor %}
            {% if results.paginator.num_pages > results.number|add:'5' %}
                <li class="page-item active}"><a class="page-link" href="?q={{ query }}&amp;page={{ results.number|add:'5' }}">&hellip;</a></li>
            {% endif %}                                    
            <li class="page-item {% if not results.has_next %} disabled {% endif %}"><a class="page-link" href="{% if results.has_next %}?q={{ query }}&amp;page={{ results.next_page_number }}{% endif %}">Next</a>
            <li class="page-item" style="padding: 0.3rem 0.75rem">(Page {{ results.number }} of {{ results.paginator.num_pages }})</li>
        </ul>
    </nav>
{% endif %}

Редактировать:

представление представляет собой код запроса стога сена ниже:

from haystack.query import SearchQuerySet
from haystack.inputs import AutoQuery, Exact, Clean
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
sqs = SearchQuerySet().filter(content=AutoQuery(query))
# create the pagination
paginator = Paginator(sqs, 10)
page = request.GET.get('page')
try:
    results = paginator.page(page)
except PageNotAnInteger:
    results = paginator.page(1)
except EmptyPage:
    results = paginator.page(paginator.num_pages)

Возвращенный объект SQS:

>>> sqs
<SearchQuerySet: query=<haystack.backends.elasticsearch5_backend.Elasticsearch5SearchQuery object at 0x7ff0e549f5f8>, using=None>
>>> vars(sqs[0])
{'app_label': 'config', 'model_name': 'devicecircuitsubnets', 'pk': '6788', 'score': 8.327476, '_object': None, '_model': None, '_verbose_name': None, '_additional_fields': ['id', 'text'], '_point_of_origin': None, '_distance': None, 'stored_fields': None, 'log': <haystack.utils.log.LoggingFacade object at 0x7ff0e525e7f0>, 'id': 'config.devicecircuitsubnets.6788', 'text': 'WAN-EDGE\nBarb\n\n\n\n\n102.155.156.2\nRouted Link\n\n'}
>>>
>>> sqs.count()
44

поэтому первая перегруппировка будет выполнена с именем модели и оценкой, что должно создать x количество model_groups с x количеством результатов в каждой из них, и эти результаты должны быть разбиты на страницы... надеюсь, все это имеет смысл?

РЕДАКТИРОВАТЬ:

вот полный вывод поиска, а затем список объектов после разбиения на страницы

>>> from haystack.query import SearchQuerySet
>>> from haystack.inputs import AutoQuery, Exact, Clean
>>> from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
>>> query ='edge'
>>> sqs = SearchQuerySet().filter(content=AutoQuery(query))
>>> paginator = Paginator(sqs, 10)
>>> page = 1
>>> results = paginator.page(page)
>>> results
<Page 1 of 5>
>>> var(results)
>>> vars(results)
{'object_list': [<SearchResult: config.devicecircuitsubnets (pk='6788')>, <SearchResult: config.devicecircuitsubnets (pk='6992')>, <SearchResult: config.devicecircuitsubnets (pk='7276')>, <SearchResult: config.device (pk='5')>, <SearchResult: config.devicecircuitsubnets (pk='694')>, <SearchResult: config.devicecircuitsubnets (pk='702')>, <SearchResult: config.devicecircuitsubnets (pk='7405')>, <SearchResult: config.devicecircuitsubnets (pk='695')>, <SearchResult: config.devicecircuitsubnets (pk='700')>, <SearchResult: config.devicecircuitsubnets (pk='1804')>], 'number': 1, 'paginator': <django.core.paginator.Paginator object at 0x7f30517037f0>}
>>> results.object_list
[<SearchResult: config.devicecircuitsubnets (pk='6788')>, <SearchResult: config.devicecircuitsubnets (pk='6992')>, <SearchResult: config.devicecircuitsubnets (pk='7276')>, <SearchResult: config.device (pk='5')>, <SearchResult: config.devicecircuitsubnets (pk='694')>, <SearchResult: config.devicecircuitsubnets (pk='702')>, <SearchResult: config.devicecircuitsubnets (pk='7405')>, <SearchResult: config.devicecircuitsubnets (pk='695')>, <SearchResult: config.devicecircuitsubnets (pk='700')>, <SearchResult: config.devicecircuitsubnets (pk='1804')>]
>>> vars(results.object_list[0])
{'app_label': 'config', 'model_name': 'devicecircuitsubnets', 'pk': '6788', 'score': 8.327476, '_object': None, '_model': None, '_verbose_name': None, '_additional_fields': ['id', 'text'], '_point_of_origin': None, '_distance': None, 'stored_fields': None, 'log': <haystack.utils.log.LoggingFacade object at 0x7f3050c83ba8>, 'id': 'config.devicecircuitsubnets.6788', 'text': 'WAN-EDGE\nBarb\n\n\n\n\n10.1.1.1\nRouted Link\n\n'}
>>>

Спасибо


person AlexW    schedule 03.10.2019    source источник
comment
Шаблон здесь не очень актуален, я думаю, вам нужно опубликовать свой код просмотра, потому что вам нужно будет изменить QuerySet, который передается в шаблон.   -  person Nico Griffioen    schedule 03.10.2019
comment
Доброе утро, я добавил код просмотра, это запрос стога сена. Спасибо   -  person AlexW    schedule 04.10.2019
comment
Не могли бы вы просто иметь два разных пагинатора? По одному на каждую группу?   -  person Karuhanga    schedule 07.10.2019
comment
да, возможно, это звучит так, как будто это может сработать, как бы я это сделал?   -  person AlexW    schedule 07.10.2019
comment
Обновите модели, которые вы используете, и представление всего.   -  person Lord Elrond    schedule 10.10.2019
comment
Кроме того, откуда AutoQuery? А откуда SearchQuerySet?   -  person Lord Elrond    schedule 10.10.2019
comment
может дубликат этого? stackoverflow.com/ вопросы/10511873/   -  person Kevin Eaverquepedo    schedule 10.10.2019
comment
Привет, запросы импортируются из модуля стога сена, я добавил их во фрагмент. возвращаемые данные являются объектом стога сена. в котором есть данные модели, я добавил образец объекта и то, как мне нравится их перегруппировка и сортировка   -  person AlexW    schedule 10.10.2019
comment
@AlexW Вам нужно опубликовать поля/члены в results.object_list. regroup должен работать на вас, но если у вас возникли трудности с реализацией, нам нужно больше информации о вашей ситуации, чтобы помочь.   -  person schillingt    schedule 10.10.2019
comment
@schillingt добавил эти данные сейчас, если это поможет?   -  person AlexW    schedule 11.10.2019


Ответы (1)


В итоге я просто отправил запрос sqs в отсортированный шаблон Django, а затем перегруппировал и использовал запрос для разбиения на страницы каждого столбца.

образец ниже:

<div class="col-lg-12">
    <div class="row">
    {% if query %}
        {% regroup results|dictsort:"model_name" by model_name as grouped_objects %}
        {% for ct in grouped_objects %}
            <div class="col-6 col-lg-3">
                <h3 class="text-capitalize">{{ ct.grouper|friendly_search_name }}</h3>
                <ul id="pager_{{ ct.grouper }}" class="pagination-sm mt-1"></ul>
                <div id="pager_content_{{ ct.grouper }}">
                    {% for result in ct.list %}
                    <div class="col-12 results item">
                        <div class="pt-4 border-bottom">
                            <a class="page-url h4 text-primary" href="{{ result.object.get_absolute_url }}">{{ result.object.get_search_title }}</a>
                            <p class="page-description mt-1 text-muted"> {{ result.object.get_search_text|safe }}</p>
                        </div>
                    </div>
                    {% endfor %}
                </div>
            </div>
        {% empty %}
            <p class="lead">Although I am a guru, I am lacking sentience. One must ask a specific question to recieve a specific answer.</p>
        {% endfor %}
    {% else %}
        {# Show some example queries to run, maybe query syntax, something else? #}
    {% endif %}
    </div>
</div>

JQuery:

{% block extrajs %}
<script src="{% static 'scripts/twbs-pagingation/jquery.twbsPagination.js' %}" type="text/javascript"></script>
<script type="text/javascript">
window.jQuery(function(){
    var items_per_page = 4;
    function hide_all(child) {
        child.removeClass('active');   
    }
    function show_page(child, num, items_per_page) {
        hide_all(child);
        child.slice((num-1)*items_per_page, num*items_per_page).addClass('active');
    }
{% regroup results|dictsort:"model_name" by model_name as grouped_objects %}
{% for ct in grouped_objects %}   
    var $content_{{ ct.grouper }} = $('#pager_content_{{ ct.grouper }}');
    var $child_{{ ct.grouper }} = $content_{{ ct.grouper }}.children();
    $('#pager_{{ ct.grouper }}').twbsPagination({
        totalPages: Math.ceil($child_{{ ct.grouper }}.length/items_per_page),
        visiblePages: 5,
        onPageClick: function (event, page) {
            show_page($child_{{ ct.grouper }}, page, items_per_page);
        }
    });
{% endfor %}
});
</script>
{% endblock extrajs %}
{% block extrastyle %}
<style type="text/css">
.item {
    display: none;
}
.item.active {
    display: block;   
}
</style>
{% endblock extrastyle %}
person AlexW    schedule 16.10.2019