【问题标题】:Django pagination returning %20 whitespace in URLDjango 分页在 URL 中返回 %20 空格
【发布时间】:2020-06-19 19:51:18
【问题描述】:

我不明白为什么 Django 分页有时会在 URL 中添加空格 (%20):

https://example.com/accounts/?page=2%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20&q=%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20&ordering=-date_joined

如果我单击Next 或特定页面按钮就会发生这种情况,因此我认为它与分页的编写方式有关。更具体地,我认为它与request.GET.items 有关。上下文管理器是否使用request.GET.items

分页

{% if page_obj.has_next %}
<a class="btn btn-default btn-inactive mb-4 m-1"
   href="?page={{ page_obj.next_page_number }}{% for key, value in request.GET.items %}
   {% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">Next</a>
<a class="btn btn-default btn-inactive mb-4 m-1"
   href="?page={{ page_obj.paginator.num_pages }}{% for key, value in request.GET.items %}
   {% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">Last</a>
{% endif %}

查看

class AccountStatusListView(AccountSearchMixin, ListView):
    model = Employee
    template_name = 'employees/account_list.html'
    paginate_by = 15

    def get_ordering(self, *args, **kwargs):
        ordering = self.request.GET.get('ordering', '-is_active')
        return ordering

    def get_queryset(self, *args, **kwargs):
        queryset = super(AccountStatusListView, self).get_queryset()

        queryset = queryset.filter(Q(
            supervisor__exact=self.request.user)) | queryset.filter(Q(
            supervisor__isnull=False)) | queryset.filter(Q(
            is_active__exact=False))

        ordering = self.get_ordering()
        if ordering and isinstance(ordering, str):
            ordering = (ordering,)
            queryset = queryset.order_by(*ordering)

        return queryset

有人知道这里发生了什么吗?

【问题讨论】:

  • for 循环将呈现空间。
  • 我该如何解决这个问题?有没有办法避免这种情况?奇怪的是它只是偶尔发生。我是否必须明确说明要附加到 URL 的内容?似乎效率低下

标签: html python-3.x django


【解决方案1】:

您可以将QueryDict 传递给模板,例如:

class AccountStatusListView(AccountSearchMixin, ListView):
    model = Employee
    template_name = 'employees/account_list.html'
    paginate_by = 15

    def get_context_data(self, *args, **kwargs):
        get_params = self.request.GET.copy()
        get_params.pop('page', None)
        return super().get_context_data(*args, **kwargs, get_params=get_params)

    def get_ordering(self, *args, **kwargs):
        return self.request.GET.get('ordering', '-is_active')

    def get_queryset(self, *args, **kwargs):
        queryset = super(AccountStatusListView, self).get_queryset()
        queryset = queryset.filter(Q(
            supervisor__exact=self.request.user)) | queryset.filter(Q(
            supervisor__isnull=False)) | queryset.filter(Q(
            is_active__exact=False))
        ordering = self.get_ordering()
        if ordering and isinstance(ordering, str):
            ordering = (ordering,)
            queryset = queryset.order_by(*ordering)
        return queryset

在模板中,你可以接着.urlencode() [Django-doc]get_params

{% if page_obj.has_next %}
<a class="btn btn-default btn-inactive mb-4 m-1"
   href="?page={{ page_obj.next_page_number }}&{{ get_params.urlencode }}">Next</a>
<a class="btn btn-default btn-inactive mb-4 m-1"
   href="?page={{ page_obj.paginator.num_pages }}&{{ get_params.urlencode }}">Last</a>
{% endif %}

【讨论】:

  • 我试过了,我的数据没有显示出来。关于为什么会这样的想法?
  • @DavidAlford:您确实将get_params 传递给上下文?我忘了回super().get_context_data()
  • 不确定你的意思。但是当我print(get_params) 在弹出'page' 之前返回一个空的QeuryDict:&lt;QueryDict: {}&gt;
  • @DavidAlford:request.GET 是否包含其他除了 page 参数?
  • 应该包含ordering和一个搜索query。在context_data 方法中弹出'page' 可能我不明白你在做什么。你能解释一下你在context_data方法中做了什么吗?
【解决方案2】:

我在上面的答案工作时遇到了一些问题,所以我稍微更改了代码......最终结果如下所示:

def get_context_data(self, *args, **kwargs):
    context = super().get_context_data(*args, **kwargs)
    get_copy = self.request.GET.copy()
    parameters = get_copy.pop('page', True) and get_copy.urlencode()
    context['params'] = parameters
    return context
{% if page_obj.has_previous %}
<a class="btn btn-default mb-4 m-1"
   href="?page=1&{{ params }}">
    First</a>
<a class="btn btn-default mb-4 m-1"
   href="?page={{ page_obj.previous_page_number }}&{{ params }}">
    Previous</a>
{% endif %}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-29
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多