atabekdemurtaza
atabekdemurtaza

Reputation: 99

Difference between reverse and reverse_lazy?

I read more projects in Django however I didn't understand!

class SignUpView(generic.CreateView):
    form_class = UserCreationForm
    success_url = reverse_lazy('login')
    template_name = 'signup.html'

like this

Upvotes: 2

Views: 974

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476659

reverse(…) [Django-doc] is a function that, for a given view name and parameters, can construct the path. But there is a problem with resolve: it can only work if the urls.py is loaded.

Typically the views.py file is imported by the urls.py, so that means that the views.py is loaded before the urls.py. This thus means that if you call reverse(…) at the class level or in a decorator like @login_required(login_url=reverse('view-name')), it is immediately processed when you the file is loaded. At that point the paths are not yet defined, so that will error.

A solution to this is to postpone evaluation. reverse_lazy(…) [Django-doc] does this. Instead of immediately evaluating it, it simply stores the name of the view, the parameters, etc. and promises to later call reverse when necessary.

If you have a view where the reverse is called in a function for example, then this is usually not a problem, unless the function is called when you load the module of course. So one can for example define a function:

from django.urls import reverse

class SignUpView(generic.CreateView):
    form_class = UserCreationForm
    template_name = 'signup.html'

    def get_success_url(self, *args, **kwargs):
        return reverse('login')

This works because here .get_success_url(…) is only called when the view is invoked and was successful. This is long after the paths are loaded.

Upvotes: 3

Related Questions