带分页的 Django 过滤器:按下一步后显示同一页面 url
django filters with pagination: showing same page after pressing next url
当我搜索某些东西(比如 tom)时,它在第一页上效果很好。但是如果我点击下一页url,它显示相同的结果,没有任何变化,但是在url,它变成了http://127.0.0.1:8000/search/?caption=tom to http://127.0.0.1:8000/search/?caption=tom&?page=2
filters.py:
class VideoFilter(django_filters.FilterSet):
class Meta:
model = Video
fields = ['caption']
filter_overrides = {
models.CharField: {
'filter_class': django_filters.CharFilter,
'extra': lambda f: {
'lookup_expr': 'icontains',
},
},
}
views.py:
def search(request):
queryset = Video.objects.all()
filterset = VideoFilter(request.GET, queryset=queryset)
if filterset.is_valid():
queryset = filterset.qs
paginator = Paginator(queryset, 2)
page_number = request.GET.get('page')
print(page_number)# always prints **none**
queryset = paginator.get_page(page_number)
return render(request, 'search.html',{
'result': queryset,
'caption': request.GET['caption'],
})
search.html:
{% extends 'navbar.html' %}
{% block body %}
<!-- more code -->
{% if result.has_next %}
<a href="?caption={{caption}}&?page={{result.next_page_number}}"><button>See more results</button></a>
{% endif %}
{% endblock body %}
navbar.html:
<!-- more code -->
<form action="/search/" method="GET"> <!-- working without csrf_token -->
<input type="text" placeholder="Search" id="search" name="caption" required />
<button type="submit">Search</button>
</form>
问题出在哪里?
我如何访问下一页?
您在按钮的 URL 中输入错误,query string [wiki] 中的 key-value 对由 符号 分隔( &
),而不是带问号的符号 (&?
)。通过这样写,Django 会将其解释为:
>>> QueryDict('caption=tom&?page=2')
<QueryDict: {'caption': ['tom'], '?page': ['2']}>
那么参数就不是page
,而是?page
.
我们可以通过删除 URL 中标题和页面之间的问号来解决此问题:
<a href="?caption={{ caption|urlencode }}<b>&</b>page={{ result.next_page_number }}">
您还应该使用 |urlencode
template filter [Django-doc] to prevent a wrong querystring, for example when the caption would have a questionmark, number sign (#
), etc. The |urlencode
filter will transform the text in percent encoding [wiki]。
当我搜索某些东西(比如 tom)时,它在第一页上效果很好。但是如果我点击下一页url,它显示相同的结果,没有任何变化,但是在url,它变成了http://127.0.0.1:8000/search/?caption=tom to http://127.0.0.1:8000/search/?caption=tom&?page=2
filters.py:
class VideoFilter(django_filters.FilterSet):
class Meta:
model = Video
fields = ['caption']
filter_overrides = {
models.CharField: {
'filter_class': django_filters.CharFilter,
'extra': lambda f: {
'lookup_expr': 'icontains',
},
},
}
views.py:
def search(request):
queryset = Video.objects.all()
filterset = VideoFilter(request.GET, queryset=queryset)
if filterset.is_valid():
queryset = filterset.qs
paginator = Paginator(queryset, 2)
page_number = request.GET.get('page')
print(page_number)# always prints **none**
queryset = paginator.get_page(page_number)
return render(request, 'search.html',{
'result': queryset,
'caption': request.GET['caption'],
})
search.html:
{% extends 'navbar.html' %}
{% block body %}
<!-- more code -->
{% if result.has_next %}
<a href="?caption={{caption}}&?page={{result.next_page_number}}"><button>See more results</button></a>
{% endif %}
{% endblock body %}
navbar.html:
<!-- more code -->
<form action="/search/" method="GET"> <!-- working without csrf_token -->
<input type="text" placeholder="Search" id="search" name="caption" required />
<button type="submit">Search</button>
</form>
问题出在哪里? 我如何访问下一页?
您在按钮的 URL 中输入错误,query string [wiki] 中的 key-value 对由 符号 分隔( &
),而不是带问号的符号 ()。通过这样写,Django 会将其解释为:&?
>>> QueryDict('caption=tom&?page=2')
<QueryDict: {'caption': ['tom'], '?page': ['2']}>
那么参数就不是,而是page
?page
.
我们可以通过删除 URL 中标题和页面之间的问号来解决此问题:
<a href="?caption={{ caption|urlencode }}<b>&</b>page={{ result.next_page_number }}">
您还应该使用 |urlencode
template filter [Django-doc] to prevent a wrong querystring, for example when the caption would have a questionmark, number sign (#
), etc. The |urlencode
filter will transform the text in percent encoding [wiki]。