TAGS :Viewed: 7 - Published at: a few seconds ago

[ Redirect using CBV's in Django ]

I believe this is a simple one, just can't spot the solution. I have a view that does a bit of work on the server then passes the user back to another view, typically the original calling view.

The way I'm rendering it now, the url isn't redirected, ie it's the url of the original receiving view. So in the case the user refreshes, they'll run that server code again.

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

Answer 1

when a user does an action and I need to redirect him to the same page, first of all I use a templateView to display a simple "thanks" (for example) then provide a link to go back to the previous page with a simple {% url %}

for example :

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).\
        context['sentance'] = 'Your service has been successfully created'
        return context

in the template thanks_service.html i use {% url %} to go back to the expected page

Hope this can help

Answer 2

Performing a redirect in a Django Class Based View is easy.

Simply do a return redirect('your url goes here').

However, I believe this isn't what you want to do. I see you're using get(). Normally, when speaking about HTTP, a GET request is seldom followed by a redirect. A POST request is usually followed by a redirect because when the user goes backwards you wouldn't want to submit the same data again.

So what do you want to do? What I think you want to do is this:

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

or even better

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

Answer 3

If you're creating or updating a model, consider inheriting from CreateView or UpdateView and specifying a success_url.

If you're really doing a redirect off of an HTTP GET action, you can inherit from RedirectView and override the get method (optionally also specifying 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)

Note that it's really bad practice to have a get action with side-effects (unless it's just populating a cache or modifying non-essential data). In most cases, you should consider using a form-based or model-form-based view, such as CreateView or UpdateView as suggested above.

Answer 4

I strongly recommend not overriding get or post methods. Instead, override dispatch. So, to expand on Platinum Azure's answer:

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)