Django 分页和过滤器附加到 url 而不是替换
Django Pagination & Filters appending to url rather than replacing
我有一个 Django 页面,其中有一个 table 来显示来自我的模型的数据。这个 table 有分页和多个过滤器。我已经设法让分页和过滤器在一定程度上协同工作,但是 URL 都搞砸了。看起来它正在将新查询字符串附加到 URL.
的末尾
我有两个主要问题:
- 如果我使用单个过滤器,它会为所有过滤器添加 URL 中的所有空查询字符串。
- 如果我在 table 中过滤了数据并尝试更改页面,它会在末尾附加页面查询字符串而不是替换它。
问题 1 的屏幕截图:
问题 2 的屏幕截图:
filters.py:
class SetFilter(django_filters.FilterSet):
name = CharFilter(field_name='name', lookup_expr='icontains', label='', )
type = AllValuesFilter(field_name='type', choices=Set.objects.values_list('type', flat=True).distinct().order_by('type'), label='', empty_label="")
nonfoil = AllValuesFilter(field_name='is_non_foil_only', choices=Set.objects.values_list('is_non_foil_only', flat=True).distinct().order_by('is_non_foil_only'), label='', empty_label="")
foil = AllValuesFilter(field_name='is_foil_only', choices=Set.objects.values_list('is_foil_only', flat=True).distinct().order_by('is_foil_only'), label='', empty_label="")
digital = AllValuesFilter(field_name='is_online_only', choices=Set.objects.values_list('is_online_only', flat=True).distinct().order_by('is_online_only'), label='', empty_label="")
foreign = AllValuesFilter(field_name='is_foreign_only', choices=Set.objects.values_list('is_foreign_only', flat=True).distinct().order_by('is_foreign_only'), label='', empty_label="")
class Meta:
model = Set
fields = ''
views.py
def sets_page(request):
set_list = Set.objects.order_by('-id')
last_modified = set_list[0].last_modified
set_filter = SetFilter(request.GET, queryset=set_list)
set_list = set_filter.qs
paginator = Paginator(set_list, 22)
is_paginated = True if paginator.num_pages > 1 else False
page = request.GET.get('page') or 1
try:
current_page = paginator.page(page)
except InvalidPage as e:
raise Http404(str(e))
context = {
'last_modified': last_modified,
'is_paginated': is_paginated,
'current_page': current_page,
'set_filter': set_filter
}
return render(request, "main/sets.html", context)
pagination.html
{% if current_page.has_next %}
{% if 'name' in request.get_full_path %}
<a class="page-link previous-next" href="{{ request.get_full_path }}&page={{ current_page.next_page_number }}">»</a>
{% else %}
<a class="page-link previous-next" href="?page={{ current_page.next_page_number }}">»</a>
{% endif %}
{% else %}
<a class="page-link previous-next" href="">»</a>
{% endif %}
我一直在使用我之前在这里找到的模板标签解决方案,可以引用它,但我只会 post 代码片段:
如果您不知道如何操作,请创建一个模板标签。 Read here。这很容易,而且不是那么长的任务。
在您的 filters/tags 文件中添加以下代码:
@register.simple_tag(takes_context=True)
def param_replace(context, **kwargs):
d =context['request'].GET.copy()
for k,v in kwargs.items():
d[k] = v
for k in [k for k,v in d.items() if not v]:
del d[k]
return d.urlencode()
在模板中加载自定义过滤器{% load "file_name_here" ... %}
然后在您的分页链接上:
<a class="page-link" href="?{% param_replace page=current_page.next_page_number %}"> Next </a>
我有一个 Django 页面,其中有一个 table 来显示来自我的模型的数据。这个 table 有分页和多个过滤器。我已经设法让分页和过滤器在一定程度上协同工作,但是 URL 都搞砸了。看起来它正在将新查询字符串附加到 URL.
的末尾我有两个主要问题:
- 如果我使用单个过滤器,它会为所有过滤器添加 URL 中的所有空查询字符串。
- 如果我在 table 中过滤了数据并尝试更改页面,它会在末尾附加页面查询字符串而不是替换它。
问题 1 的屏幕截图:
问题 2 的屏幕截图:
filters.py:
class SetFilter(django_filters.FilterSet):
name = CharFilter(field_name='name', lookup_expr='icontains', label='', )
type = AllValuesFilter(field_name='type', choices=Set.objects.values_list('type', flat=True).distinct().order_by('type'), label='', empty_label="")
nonfoil = AllValuesFilter(field_name='is_non_foil_only', choices=Set.objects.values_list('is_non_foil_only', flat=True).distinct().order_by('is_non_foil_only'), label='', empty_label="")
foil = AllValuesFilter(field_name='is_foil_only', choices=Set.objects.values_list('is_foil_only', flat=True).distinct().order_by('is_foil_only'), label='', empty_label="")
digital = AllValuesFilter(field_name='is_online_only', choices=Set.objects.values_list('is_online_only', flat=True).distinct().order_by('is_online_only'), label='', empty_label="")
foreign = AllValuesFilter(field_name='is_foreign_only', choices=Set.objects.values_list('is_foreign_only', flat=True).distinct().order_by('is_foreign_only'), label='', empty_label="")
class Meta:
model = Set
fields = ''
views.py
def sets_page(request):
set_list = Set.objects.order_by('-id')
last_modified = set_list[0].last_modified
set_filter = SetFilter(request.GET, queryset=set_list)
set_list = set_filter.qs
paginator = Paginator(set_list, 22)
is_paginated = True if paginator.num_pages > 1 else False
page = request.GET.get('page') or 1
try:
current_page = paginator.page(page)
except InvalidPage as e:
raise Http404(str(e))
context = {
'last_modified': last_modified,
'is_paginated': is_paginated,
'current_page': current_page,
'set_filter': set_filter
}
return render(request, "main/sets.html", context)
pagination.html
{% if current_page.has_next %}
{% if 'name' in request.get_full_path %}
<a class="page-link previous-next" href="{{ request.get_full_path }}&page={{ current_page.next_page_number }}">»</a>
{% else %}
<a class="page-link previous-next" href="?page={{ current_page.next_page_number }}">»</a>
{% endif %}
{% else %}
<a class="page-link previous-next" href="">»</a>
{% endif %}
我一直在使用我之前在这里找到的模板标签解决方案,可以引用它,但我只会 post 代码片段:
如果您不知道如何操作,请创建一个模板标签。 Read here。这很容易,而且不是那么长的任务。
在您的 filters/tags 文件中添加以下代码:
@register.simple_tag(takes_context=True)
def param_replace(context, **kwargs):
d =context['request'].GET.copy()
for k,v in kwargs.items():
d[k] = v
for k in [k for k,v in d.items() if not v]:
del d[k]
return d.urlencode()
在模板中加载自定义过滤器{% load "file_name_here" ... %}
然后在您的分页链接上:
<a class="page-link" href="?{% param_replace page=current_page.next_page_number %}"> Next </a>