Django накладные расходы с сортировкой - PullRequest
2 голосов
/ 11 июля 2011

Я пытаюсь реализовать структуру разбиения на страницы в Django с некоторыми опциями сортировки, однако я не могу понять, как я могу сделать это правильно.

views.py

def search(request):
    eList = Employer.objects.filter(eminence__lt=4).order_by('-eminence')

    paginator = Paginator(eList, 3) # Show 3 contacts per page

    page = request.GET.get('page')
    try:
        employerList = paginator.page(page)
    except PageNotAnInteger:
        employerList = paginator.page(1)
    except EmptyPage:
        employerList = paginator.page(paginator.num_pages)

return render_response(request, 'employer/search.html', {'employerList':employerList})

search.html

<div class="pagination">
    <span class="step-links">
        {% if employerList.has_previous %}
            <a href="?page={{ employerList.previous_page_number }}">previous</a>
        {% endif %}

        <span class="current"> Page {{ employerList.number }} of {{ employerList.paginator.num_pages }}.</span>
        {% if employerList.has_next %}
            <a href="?page={{ employerList.next_page_number }}">next</a>
        {% endif %}
    </span>
</div>

Однако этот пример прекрасно работает, как вы можете видеть, для каждой навигации мне нужно получить все Employer объекты.После этого Paginator обрабатывает объекты в запросе в зависимости от номера страницы.Тем не менее, я думаю, что нумерация страниц должна выполняться во время запроса и получать только те X-объекты, которые мне нужны, в зависимости от номера страницы.Конечно, я могу изменить код таким образом, но я не могу понять, почему люди используют Paginator, хотя есть такие издержки.Я могу упустить из виду детали ...

Мой второй вопрос: как я могу применить сортировку моего списка?Должен ли я изменить свой url и передать метод сортировки и номер страницы, и в зависимости от них получить запрос методом сортировки и присвоить ему Paginator?

Это кажется мне разумным и хорошим, но я простоИнтересно, есть ли лучший способ сделать в Джанго.

Спасибо

Ответы [ 3 ]

6 голосов
/ 11 июля 2011

Django очень лениво загружает данные, что делает эти запросы очень эффективными. Давайте разберемся, что происходит с вашими запросами ...

eList = Employer.objects.filter(eminence__lt=4).order_by('-eminence')
## No database query.

paginator = Paginator(eList, 3)
## No database query.

employerList = paginator.page(2)
## SELECT COUNT(*) FROM `yourproject_employer`
## WHERE `yourproject_employer`.`eminence` < 4

 # Force iteration.  Same as looping over results:
foo = list(employerList.object_list)
## SELECT * FROM `yourproject_employer`
## WHERE `yourproject_employer`.`eminence` < 4
## ORDER BY `yourproject_employer`.`eminence` DESC
## LIMIT 3 OFFSET 3

Что касается вашего вопроса сортировки, я бы сказал, что просто измените аргументы GET, как вы предложили. Просто будьте очень осторожно передавая это в базу данных. Я, например, составил бы список возможных сортировок и проверил бы это. Это также означает, что вам не нужно раскрывать внутреннюю работу вашей базы данных.

VALID_SORTS = {
    "pk": "pk",
    "pkd": "-pk",
    "em": "eminence",
    "emd": "-eminence",
}
DEFAULT_SORT = 'pk'
def search(request):
    sort_key = request.GET.get('sort', DEFAULT_SORT) # Replace pk with your default.
    sort = VALID_SORTS.get(sort_key, DEFAULT_SORT)

    eList = Employer.objects.filter(eminence__lt=4).order_by(sort)
0 голосов
/ 27 октября 2012

На самом деле Paginator зависит от нарезки QuerySet.Слайсинг зависит от конкретной базы данных - если адаптер django db поддерживает это (например, переносит ограничения слайсов в SQL-запрос - что-то вроде LIMIT x OFFSET y для mysql или что-то еще для других db).Если это поддерживается, то запрос выбирает только строки для данной страницы.
Я считаю, что для MySQL эта функция сейчас отключена (я рассматривал Django 1.3) из-за проблемы с производительностью предложения OFFSET.

0 голосов
/ 12 июля 2011

Я бы настоятельно рекомендовал endless_pagination.Это удивительное приложение.Проверьте пример проекта здесь: https://github.com/venkasub/endless_pagination_example

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...