如何对从多个上下文对象中选择的get_context_data进行分页? [英] How can I paginate get_context_data choosing from among multiple context objects?

查看:120
本文介绍了如何对从多个上下文对象中选择的get_context_data进行分页?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过从多个上下文对象中进行选择来对views.py中的get_context_data进行分页.代码示例条件语句中仅显示了两个选择,但是我还有其他几个选择,这些选择基本上涵盖了表单提交中的所有选择.仅返回一个上下文,但是最后将上下文传递到模板视图以进行分页.

I am trying to paginate get_context_data from views.py, by selecting from among multiple context objects. Only two choices are shown in the code example conditional statements, but I have several more choices which basically cover all choices from the form submission. Only one context is returned, in the end however, passing the context to the template view for pagination.

我也尝试在settings.py中全局设置分页,但是它不起作用.

I tried also setting pagination globally in settings.py, but it is not working.

我以前已经看过下面的文章,作为对get-context-objects进行分页的指南.

I have viewed the article below, previously, as a guide to pagination on get-context-objects.

如何在Django中对上下文对象执行分页? /a>

How to perform pagination for context object in django?

来自views.py:

From views.py:

from django.shortcuts import render
import django.views.generic
from django.http import HttpResponse
from django.template import loader
from django.template import RequestContext
from ephemera.models import *
from ephemera.serializers import ItemSerializer
from rest_framework import generics
from ephemera.forms import SearchForm, AdvSearchForm
from itertools import chain
from django.core.paginator import Paginator
from django.core.paginator import EmptyPage
from django.core.paginator import PageNotAnInteger



class SearchResultsAdvancedView(django.views.generic.ListView): 
    template_name = 'ephemera/searchresults_advanced.html'
    form = AdvSearchForm()
    paginate_by = 10
    model = Item

    def get_context_data(self, **kwargs):       
        context = super(SearchResultsAdvancedView, self).get_context_data(**kwargs)

        choose_collection = self.request.GET.get('choose_collection')
        user_input = self.request.GET.get('user_input')
        choose_item = self.request.GET.get('choose_item')

        bookpage = False
        imagepage = False

        if choose_collection == 'All' and user_input == '' and choose_item == 'book':
            context['book_qs'] = Item.objects.raw('SELECT  * FROM   ephemera_item WHERE ephemera_item.material_type LIKE %s', ['book']);    
            bookpage = True
        elif choose_collection == 'All' and user_input == '' and choose_item == 'image':
            context['image_qs'] = Item.objects.raw('SELECT  * FROM   ephemera_item WHERE ephemera_item.material_type LIKE %s', ['image']);  
            imagepage = True

        if bookpage:
            paginator = Paginator(context, self.paginate_by)            
            page = self.request.GET.get('page')
            try:
                book_qs = paginator.page(page)
            except PageNotAnInteger:
                book_qs = paginator.page(1)
            except EmptyPage:
                book_qs = paginator.page(paginator.num_pages)
            context['book_qs'] = book_qs

        elif imagepage:
            paginator = Paginator(context, self.paginate_by)            
            page = self.request.GET.get('page')
            try:
                image_qs = paginator.page(page)
            except PageNotAnInteger:
                image_qs = paginator.page(1)
            except EmptyPage:
                image_qs = paginator.page(paginator.num_pages)
            context['image_qs'] = image_qs

        return context

返回的错误包括:

异常值:不可散列的类型:'sl​​ice'

Exception Value: unhashable type: 'slice'

异常位置:页面70行中的c:\ users \ administrator \ appdata \ local \ programs \ python \ python36-32 \ lib \ site-packages \ django \ core \ paginator.py

Exception Location: c:\users\administrator\appdata\local\programs\python\python36-32\lib\site-packages\django\core\paginator.py in page, line 70

推荐答案

无需使用

There is no need to use get_context_data [Django-doc] here, you can override get_queryset [Django-doc] and get_context_object_name [Django-doc] to determine the name of the list in your template:

class SearchResultsAdvancedView(django.views.generic.ListView): 
    template_name = 'ephemera/searchresults_advanced.html'
    form = AdvSearchForm()
    paginate_by = 10
    model = Item

    def item_type(self):
        choose_collection = self.request.GET.get('choose_collection')
        if choose_collection != 'All' or not self.request.GET.get('user_input'):
            return None
        choose_item = self.request.GET.get('choose_item')
        if choose_item in ('book', 'image'):
            return choose_item
        return None

    def get_queryset(self, *args, **kwargs):
        item_type = self.get_item_type()
        qs = super.get_queryset(*args, **kwargs)
        if item_type is not None:
            return qs.filter(material_type__iexact=item_type)
        return qs.none()

    def get_context_object_name(self, object_list):
        item_type = self.get_item_type()
        if item_type is not None:
            return '{}_qs'.format(item_type)
        return super().get_context_object_name(object_list)

Django的逻辑将对QuerySet本身进行分页,因此您不必担心.这是由于 MultipleObjectMixin [Django-doc] :

Django's logic will paginate the QuerySet itself, you thus do not need to worry about that. This is due to the get_context_data [Django-doc] implementation of the MultipleObjectMixin [Django-doc]:

def get_context_data(self, *, object_list=None, **kwargs):
    """Get the context for this view."""
    queryset = object_list if object_list is not None else self.object_list
    page_size = self.get_paginate_by(queryset)
    context_object_name = self.get_context_object_name(queryset)
    if page_size:
        paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size)
        context = {
            'paginator': paginator,
            'page_obj': page,
            'is_paginated': is_paginated,
            'object_list': queryset
        }
    else:
        context = {
            'paginator': None,
            'page_obj': None,
            'is_paginated': False,
            'object_list': queryset
        }
    if context_object_name is not None:
        context[context_object_name] = queryset
    context.update(kwargs)
    return super().get_context_data(**context)

话虽这么说,但我的印象是建模效果不佳.如果您具有项目类型,则必须定义一个ItemType模型.此外,您最好使用Django的ORM来生成查询,而不是原始查询.

That being said, I have the impression that the modeling is not done very well. If you have types of items, it makes sence to define an ItemType model. Furthermore you better use Django's ORM to generate queries instead of raw queries.

这篇关于如何对从多个上下文对象中选择的get_context_data进行分页?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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