【问题标题】:Redirect using CBV's in Django在 Django 中使用 CBV 进行重定向
【发布时间】:2013-09-05 21:58:07
【问题描述】:

我相信这是一个简单的问题,只是无法找到解决方案。我有一个视图,它在服务器上做了一些工作,然后将用户传回另一个视图,通常是原始调用视图。

我现在渲染它的方式,url 没有被重定向,即它是原始接收视图的 url。因此,在用户刷新的情况下,他们将再次运行该服务器代码。

class CountSomethingView(LoginRequiredMixin, View):
    def get(self, request, *args, **kwargs):
        # so some counting
        view = MyDetailView.as_view()
        return view(request, *args, **kwargs)

【问题讨论】:

  • 您需要重定向还是使用了错误的术语?通常 HTTP get 后面永远不会有重定向。

标签: python django redirect django-class-based-views


【解决方案1】:

我强烈建议不要覆盖 getpost 方法。相反,覆盖dispatch。因此,扩展 Platinum Azure 的答案:

class CountSomethingView(LoginRequiredMixin, RedirectView):
    permanent = False

    def get_redirect_url(self, **kwargs):
        url = you_can_define_the_url_however_you_want(**kwargs)
        return url

    def dispatch(self, request, *args, **kwargs):
        # do something
        return super(CountSomethingView, self).dispatch(request, *args, **kwargs)

【讨论】:

  • 为什么强烈建议不要覆盖 get 和 post 方法?
  • 好吧,从技术上讲,您可以覆盖它们,但是您将失去默认实现包含的所有内部方法的好处。例如DetailView类知道如何实例化模型实例,而getpost已经知道如何在内部使用这些知识(看[方法流程图][docs.djangoproject.com/en/1.11/ref/class-based-views/…了解里面到底发生了什么风景)。所以问题是你到底想修改什么行为,然后只修改提供该行为的方法。
  • 当然,您的用例可能不适合预定义的视图,您需要从头开始实现 getpost,但是您应该扩展其中一个基本视图,比如View
【解决方案2】:

当用户执行操作并且我需要将他重定向到同一页面时,首先我使用 templateView 显示一个简单的“谢谢”(例如),然后提供一个链接以返回上一页一个简单的{% url %}

例如:

from django.views.generic import CreateView, TemplateView
from django.http import HttpResponseRedirect

class UserServiceCreateView(CreateView):
    form_class = UserServiceForm
    template_name = "services/add_service.html"

    def form_valid(self, form):
    [...]

    return HttpResponseRedirect('/service/add/thanks/')

class UserServiceAddedTemplateView(TemplateView):
     template_name = "services/thanks_service.html"

    def get_context_data(self, **kw):
        context = super(UserServiceAddedTemplateView, self).\
            get_context_data(**kw)
        context['sentance'] = 'Your service has been successfully created'
        return context

在模板Thanks_service.html 中我使用{% url %} 返回预期页面

希望对你有帮助

【讨论】:

    【解决方案3】:

    在基于 Django 类的视图中执行重定向很容易。

    只需做一个return redirect('your url goes here')

    但是,我相信这不是您想要做的。 我看到你正在使用get()。 通常,在谈到 HTTP 时,GET 请求很少会跟随重定向。 POST 请求后通常会进行重定向,因为当用户向后退时,您不想再次提交相同的数据。

    那你想做什么? 我认为你想要做的是:

    def get(self, request, *args, **kwargs):
       return render_to_response('your template', data)
    

    甚至更好

    def get(self, request, *args, **kwargs):
        return render(request, self.template_name, data)
    

    【讨论】:

      【解决方案4】:

      如果您正在创建或更新模型,请考虑从CreateViewUpdateView 继承并指定success_url

      如果您确实是从 HTTP GET 操作进行重定向,您可以从 RedirectView 继承并覆盖 get 方法(也可以指定 permanent = False):

      class CountSomethingView(LoginRequiredMixin, RedirectView):
          permanent = False
      
          def get(self, request, *args, **kwargs):
              # do something
              return super(CountSomethingView, self).get(self, request, *args, **kwargs)
      

      请注意,使用带有副作用的 get 操作是非常糟糕的做法(除非它只是填充缓存或修改非必要数据)。在大多数情况下,您应该考虑使用基于表单或基于模型表单的视图,例如上面建议的CreateViewUpdateView

      【讨论】:

        猜你喜欢
        • 2018-06-04
        • 2020-03-05
        • 2017-07-06
        • 2018-03-28
        • 2019-03-20
        • 1970-01-01
        • 2011-04-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多