如何对从多个上下文对象中选择的get_context_data进行分页? [英] How can I paginate get_context_data choosing from among multiple context objects?
问题描述
我试图通过从多个上下文对象中进行选择来对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.
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
返回的错误包括:
异常值:不可散列的类型:'slice'
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
推荐答案
无需使用 get_context_object_name
[Django-doc] 确定名称模板中的列表:
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屋!