【问题标题】:Django pagination - how to redirect back to a ListView and a page numberDjango 分页 - 如何重定向回 ListView 和页码
【发布时间】:2016-11-07 10:30:50
【问题描述】:

ListView 中,我使用带有paginate_by = 5 的Paginator 渲染表格。 在每一行中,我都有一个打开UpdateView 的按钮。 成功更新后,我回到了我的ListView,但总是在第一页。 如何更改success_url,以便我回到打开UpdateView 的页码? Django 中是否有适当的方法来解决这个问题?

#views.py

class Orders_list(ListView):
    model = Order
    context_object_name = "orders"
    queryset = Order.objects.all()
    paginate_by = 5
    template_name = "orders/orders_list.html"

#http://127.0.0.1:8000/orders/?page=4


class Orders_update(UpdateView):
    model = Order
    form_class = Order_UpdateForm
    template_name = "orders/orders_update.html"
    #success_url = '../../../orders/'
    success_url = reverse_lazy('orders')


#urls.py

urlpatterns = [
    url(r'^orders/$', Orders_list.as_view()),
    url(r'^orders/detail/(?P<pk>\d+)/$', Orders_detail.as_view()),
]


#forms.py

class Order_UpdateForm(forms.ModelForm):
    class Meta:
        model = Order
        fields = ['order_text', 'customer', 'cyclist']

    def __init__(self, *args, **kwargs):
        super(Order_UpdateForm, self).__init__(*args, **kwargs)
        self.fields['cyclist'].queryset = Cyclist.objects.filter(active=True)


#models.py

class Order(models.Model):
    customer = models.ForeignKey('Customer')
    cyclist = models.ForeignKey('Cyclist')
    order_text = models.CharField(max_length=200)
    pick_up = models.CharField(max_length=200)
    destination = models.CharField(max_length=200)
    created_date = models.DateTimeField(default=timezone.now)
    changed_date = models.DateTimeField(blank=True, null=True)

    def created(self):
        self.changed_date = timezone.now()
        self.save()

    def __str__(self):
        return self.order_text


class Customer(models.Model):
    company_name = models.CharField(max_length=200)
    created_date = models.DateTimeField(default=timezone.now)
    changed_date = models.DateTimeField(blank=True, null=True)

    def created(self):
        self.changed_date = timezone.now()
        self.save()

    def __str__(self): return self.company_name


class Cyclist(models.Model):
    lastname = models.CharField(max_length=20)
    firstname = models.CharField(max_length=20)
    created_date = models.DateTimeField(default=timezone.now)
    changed_date = models.DateTimeField(blank=True, null=True)
    active = models.BooleanField(default=True)

    def created(self):
        self.changed_date = timezone.now()
        self.save()

    def __str__(self):
        return self.lastname

更新

我找到了解决这个问题的方法(可能)。但我还是想念一些东西。

到目前为止我做了什么:

ListView 模板中我扩展了Url...

window.open("{{ request.path }}update/" + id + "/?page=" + {{ page_obj.number }});

...然后在视图中我覆盖了get_context_data 方法...

#views.py

class Orders_update(UpdateView):
    model = Order
    form_class = Order_UpdateForm
    template_name = "orders/orders_update.html"
    page = "1" # Assigned

    def get_context_data(self, **kwargs):
        context = super(Orders_update, self).get_context_data(**kwargs)
        page = self.request.GET.get('page') # Modified
        return context

    success_url = '../../../orders/?page=' + str(page) # Should be used here to redirect to a specific page on a ListView

...但是现在...如何在success_url 中访问views.py 中的变量page? 我认为这是非常基本的东西(希望如此),我想我不明白范围在 Python 中是如何工作的。

【问题讨论】:

  • 我更新了我的问题,看看views.py。
  • ListView 没有 success_url 属性或 get_success_url() 方法。所以你可以覆盖render_to_response(self, context, **response_kwargs),然后用你的url提供一个HttpResponseRedirect,你也可以提供上下文数据

标签: python django


【解决方案1】:

这最终对我有用。基本上我只是覆盖了get_success_url 以从请求中访问page 参数。

class Orders_update(UpdateView):
    model = Order
    form_class = Order_UpdateForm
    template_name = "orders/orders_update.html"

    def get_success_url(self):
        global page
        page = self.request.GET.get('page')
        return reverse_lazy('orders')

【讨论】:

    【解决方案2】:

    我刚刚解决了同样的问题。这就是我所做的。从你的 ListView、Order_list 中的 views.py 开始,并添加上下文数据:

    def get_context_data(self, **kwargs):
            kwargs['current_page'] = self.request.GET.get('page', 1)
            return super().get_context_data(**kwargs)
    

    上面的代码只将当前页码传递给 ListView 模板。 然后进入对应的列表视图模板,在对象列表循环中添加以下内容:

     {% if is_paginated %}
            <a href="{% url 'order_update' pk=order.pk %}?next={{current_page}}">Update
                </a>
                {% else %}
            <a href="{% url 'order_update' pk=order.pk %}">Update
                {% endif %}
    

    if 语句允许页面在没有分页的情况下工作。注意?next={{current_page}} 变量。 “current_page”来自视图中的 context_data。该位将当前页码传递给锚标记中页面的 url 中的“下一个”变量。这就是我的更新视图 URL 中包含这个变量的样子:http://localhost:8000/food/406/update?next=1。请参阅网址中的 ?next=1。 接下来,回到views.py到你的UpdateView,Order_update,用这段代码修改成功的url:

    def get_success_url(self, **kwargs):
            if self.request.GET.get('next'):
                return f"/orders?page={self.request.GET.get('next', 1)}"
            else:
                return '/orders'
    

    您必须在此视图中删除 success_url 声明。 def get_success_url 函数需要一个字符串。反向似乎工作得很好,但格式化字符串在 redirect() 语句中不起作用。它必须是纯字符串。有关更多信息,请参阅TypeError: quote_from_bytes() expected bytes after redirect

    如果我把它分解得太多了,我很抱歉。我不是要侮辱你的知识。我仍在学习中,并且在我弄清楚之前,我按照今天早些时候需要它的方式编写了这个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 2014-11-24
      • 2019-07-17
      • 1970-01-01
      • 1970-01-01
      • 2022-10-05
      • 2012-07-16
      相关资源
      最近更新 更多