尝试转到下一页时 Django 分页抛出错误
Django pagination throwing an error when trying to go to the next page
我目前正在从事一个将在网站上显示广告的项目。即使在研究半天试图找到解决方案但没有运气之后,我仍面临一定程度的困难。
我有一个 HomeView
它继承了 ListView
我有 paginate_by = 30
的地方,它显示在主页上,并且在转到我的任何页码方面都可以正常工作点击。
我有另一个名为 NegotiableAdView
的视图,它也继承了 ListView
。在这个视图中,我从 request.GET
得到一个值,它是 yes 或 no 然后根据 return 过滤查询集。它显示我将 paginate_by
属性设置为的广告数量,但问题是每当我点击 page 2
或它说的任何页码时,例如:
Page not found (404)... Invalid page (2): That page contains no
results
我不确定为什么会出现该错误。但是我有没有以下...
在包含以下形式的 html
文件中:
<form method="GET" action="{% url 'store:search-negotiation' %}">
<div id="collapseThreee" class="panel-collapse collapse " role="tabpanel" aria-labelledby="headingThreee">
<div class="panel-body">
<div class="skin-minimal">
<ul class="list">
<li>
<input type="radio" id="radio-yes" name="negotiable" value="Yes">
<label for="yes">Yes</label>
</li>
<li>
<input type="radio" id="radio-no" name="negotiable" value="No">
<label for="no">No</label>
</li>
</ul>
</div>
</div>
</div>
</form>
在 urls.py
文件中:
from .views import NegotiableAdView
app_name = 'store'
urlpatterns = [
...
path('search-negotiation/', NegotiableAdView.as_view(), name='search-negotiation'),
...
]
在 views.py
文件中:
class NegotiableAdView(ListView):
context_object_name = 'ads'
paginate_by = 12
template_name = 'store/pages/results.html'
def get_queryset(self, *args, **kwargs):
negotiable = self.request.GET.get('negotiable')
queryset = Advertisement.objects.filter(negotiable__iexact=negotiable).order_by('-publish', 'name')
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
negotiable = self.request.GET.get('negotiable')
# This 'negotiable' var is only not none when on the first page of the results
if negotiable:
context['result_name'] = f'Results "{negotiable.title()}"'
return context
在包含 pagination
:
的 results.html
文件中
{% for ad in ads %}
...
{% endfor %}
{% include 'store/includes/pagination.html' with pages=page_obj %}
在 pagination.html
文件中:
{% if is_paginated %}
<ul class="pagination pagination-lg">
{% if pages.has_previous %}
<li>
<a href="?page={{ pages.previous_page_number }}">« Previous Page</a>
</li>
{% endif %}
{% if pages.number|add:'-4' > 1 %}
<li>
<a href="?page={{ pages.number|add:'-5' }}">…</a>
</li>
{% endif %}
{% for number in pages.paginator.page_range %}
{% if pages.number == number %}
<li class="active">
<a href="javascript:void(0);">{{ number }}</a>
</li>
{% elif number > pages.number|add:'-5' and number < pages.number|add:'5' %}
<li>
<a href="?page={{ number }}">{{ number }}</a>
</li>
{% endif %}
{% endfor %}
{% if pages.paginator.num_pages > pages.number|add:'4' %}
<li>
<a href="?page={{ pages.number|add:'5' }}">…</a>
</li>
{% endif %}
{% if pages.has_next %}
<li>
<a href="?page={{ pages.next_page_number }}">Next Page »</a>
</li>
{% endif %}
</ul>
{% endif %}
还要注意,如果用户选择 yes,http://127.0.0.1:8000/search-negotiation/?negotiable=Yes
,结果页面上的 url
.但是,例如,当用户单击 page 2
时,我看到 http://127.0.0.1:8000/search-negotiation/?page=2
并显示如前所述的错误。
有人可以指出我做错了什么吗?任何帮助将不胜感激。
所以我有了一个想法,尝试了一下,结果成功了!我认为这可能不是解决我遇到的特定问题的最有效方法,但我就是这样做的。
因此,我在 url.py
文件中创建了一个新的 url
。
urlpatterns = [
...
path('search/', RedirectedSearchView.as_view(), name='search'), # new url
path('search-negotiation/<str:negotiable>/', NegotiableAdView.as_view(), name='search-negotiation'), # update this url for kwargs.
...
]
表单将发送 GET
请求在新的 url
处理,它也将相应地重定向。
表格:
<form method="GET" action="{% url 'store:search' %}"> <!-- updated url here -->
<div id="collapseThreee" class="panel-collapse collapse " role="tabpanel" aria-labelledby="headingThreee">
<div class="panel-body">
<div class="skin-minimal">
<ul class="list">
<li>
<input type="radio" id="radio-yes" name="negotiable" value="Yes">
<label for="yes">Yes</label>
</li>
<li>
<input type="radio" id="radio-no" name="negotiable" value="No">
<label for="no">No</label>
</li>
</ul>
</div>
</div>
</div>
</form>
在 views.py
文件中:
# This view will handle the GET request and then redirect to the necessary view.
class RedirectedSearchView(TemplateView):
def get(self, request, *args, **kwargs):
# Doing a check here to see if the form made a GET request by trying to get a value submitted
if request.GET.get('negotiable'):
# As I do the redirect, I must pass a 'negotiable' value to the url
# Assigning the value passed from the request.GET -> negotiable=request.GET.get('negotiable').lower()
return redirect('store:search-negotiation', negotiable=request.GET.get('negotiable').lower())
return redirect('store:home')
class NegotiableAdView(ListView):
context_object_name = 'ads'
paginate_by = 12
template_name = 'store/pages/results.html'
def get_queryset(self, *args, **kwargs):
# Collecting the value from the url to filter the queryset to return
negotiable = self.kwargs.get('negotiable', '')
return Advertisement.objects.filter(negotiable__iexact=negotiable).order_by('-publish', 'name')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
negotiable = self.kwargs.get('negotiable', '')
context['result_name'] = f'Results "{negotiable.title()}"'
return context
通过这种方式,我的 pagination
现在可以转到其他页面,因为它以前不会这样做。
如我所说,此解决方案可能不是最有效的解决方案。因此,我愿意接受更有效和正确的方法。
提前致谢!
我目前正在从事一个将在网站上显示广告的项目。即使在研究半天试图找到解决方案但没有运气之后,我仍面临一定程度的困难。
我有一个 HomeView
它继承了 ListView
我有 paginate_by = 30
的地方,它显示在主页上,并且在转到我的任何页码方面都可以正常工作点击。
我有另一个名为 NegotiableAdView
的视图,它也继承了 ListView
。在这个视图中,我从 request.GET
得到一个值,它是 yes 或 no 然后根据 return 过滤查询集。它显示我将 paginate_by
属性设置为的广告数量,但问题是每当我点击 page 2
或它说的任何页码时,例如:
Page not found (404)... Invalid page (2): That page contains no results
我不确定为什么会出现该错误。但是我有没有以下...
在包含以下形式的 html
文件中:
<form method="GET" action="{% url 'store:search-negotiation' %}">
<div id="collapseThreee" class="panel-collapse collapse " role="tabpanel" aria-labelledby="headingThreee">
<div class="panel-body">
<div class="skin-minimal">
<ul class="list">
<li>
<input type="radio" id="radio-yes" name="negotiable" value="Yes">
<label for="yes">Yes</label>
</li>
<li>
<input type="radio" id="radio-no" name="negotiable" value="No">
<label for="no">No</label>
</li>
</ul>
</div>
</div>
</div>
</form>
在 urls.py
文件中:
from .views import NegotiableAdView
app_name = 'store'
urlpatterns = [
...
path('search-negotiation/', NegotiableAdView.as_view(), name='search-negotiation'),
...
]
在 views.py
文件中:
class NegotiableAdView(ListView):
context_object_name = 'ads'
paginate_by = 12
template_name = 'store/pages/results.html'
def get_queryset(self, *args, **kwargs):
negotiable = self.request.GET.get('negotiable')
queryset = Advertisement.objects.filter(negotiable__iexact=negotiable).order_by('-publish', 'name')
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
negotiable = self.request.GET.get('negotiable')
# This 'negotiable' var is only not none when on the first page of the results
if negotiable:
context['result_name'] = f'Results "{negotiable.title()}"'
return context
在包含 pagination
:
results.html
文件中
{% for ad in ads %}
...
{% endfor %}
{% include 'store/includes/pagination.html' with pages=page_obj %}
在 pagination.html
文件中:
{% if is_paginated %}
<ul class="pagination pagination-lg">
{% if pages.has_previous %}
<li>
<a href="?page={{ pages.previous_page_number }}">« Previous Page</a>
</li>
{% endif %}
{% if pages.number|add:'-4' > 1 %}
<li>
<a href="?page={{ pages.number|add:'-5' }}">…</a>
</li>
{% endif %}
{% for number in pages.paginator.page_range %}
{% if pages.number == number %}
<li class="active">
<a href="javascript:void(0);">{{ number }}</a>
</li>
{% elif number > pages.number|add:'-5' and number < pages.number|add:'5' %}
<li>
<a href="?page={{ number }}">{{ number }}</a>
</li>
{% endif %}
{% endfor %}
{% if pages.paginator.num_pages > pages.number|add:'4' %}
<li>
<a href="?page={{ pages.number|add:'5' }}">…</a>
</li>
{% endif %}
{% if pages.has_next %}
<li>
<a href="?page={{ pages.next_page_number }}">Next Page »</a>
</li>
{% endif %}
</ul>
{% endif %}
还要注意,如果用户选择 yes,http://127.0.0.1:8000/search-negotiation/?negotiable=Yes
,结果页面上的 url
.但是,例如,当用户单击 page 2
时,我看到 http://127.0.0.1:8000/search-negotiation/?page=2
并显示如前所述的错误。
有人可以指出我做错了什么吗?任何帮助将不胜感激。
所以我有了一个想法,尝试了一下,结果成功了!我认为这可能不是解决我遇到的特定问题的最有效方法,但我就是这样做的。
因此,我在 url.py
文件中创建了一个新的 url
。
urlpatterns = [
...
path('search/', RedirectedSearchView.as_view(), name='search'), # new url
path('search-negotiation/<str:negotiable>/', NegotiableAdView.as_view(), name='search-negotiation'), # update this url for kwargs.
...
]
表单将发送 GET
请求在新的 url
处理,它也将相应地重定向。
表格:
<form method="GET" action="{% url 'store:search' %}"> <!-- updated url here -->
<div id="collapseThreee" class="panel-collapse collapse " role="tabpanel" aria-labelledby="headingThreee">
<div class="panel-body">
<div class="skin-minimal">
<ul class="list">
<li>
<input type="radio" id="radio-yes" name="negotiable" value="Yes">
<label for="yes">Yes</label>
</li>
<li>
<input type="radio" id="radio-no" name="negotiable" value="No">
<label for="no">No</label>
</li>
</ul>
</div>
</div>
</div>
</form>
在 views.py
文件中:
# This view will handle the GET request and then redirect to the necessary view.
class RedirectedSearchView(TemplateView):
def get(self, request, *args, **kwargs):
# Doing a check here to see if the form made a GET request by trying to get a value submitted
if request.GET.get('negotiable'):
# As I do the redirect, I must pass a 'negotiable' value to the url
# Assigning the value passed from the request.GET -> negotiable=request.GET.get('negotiable').lower()
return redirect('store:search-negotiation', negotiable=request.GET.get('negotiable').lower())
return redirect('store:home')
class NegotiableAdView(ListView):
context_object_name = 'ads'
paginate_by = 12
template_name = 'store/pages/results.html'
def get_queryset(self, *args, **kwargs):
# Collecting the value from the url to filter the queryset to return
negotiable = self.kwargs.get('negotiable', '')
return Advertisement.objects.filter(negotiable__iexact=negotiable).order_by('-publish', 'name')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
negotiable = self.kwargs.get('negotiable', '')
context['result_name'] = f'Results "{negotiable.title()}"'
return context
通过这种方式,我的 pagination
现在可以转到其他页面,因为它以前不会这样做。
如我所说,此解决方案可能不是最有效的解决方案。因此,我愿意接受更有效和正确的方法。
提前致谢!