Difference between reverse() and reverse_lazy() in Django
Reverse_lazy is, as the name implies, a lazy implementation of the reverse URL resolver. Unlike the traditional reverse function, reverse_lazy won't execute until the value is needed.
It is useful because it prevent Reverse Not Found exceptions when working with URLs that may not be immediately known.
Why do we need it? It's needed because, Class attributes are evaluated on import and at that time Reverse method will return 'Reverse Not Found'. Later upon need, at the time of its execution, all the necessary code snippets will be executed already, to give a valid URL.
#importme.py
def a():
print("FUNCTION HELLO")
class B():
print("CLASS HELLO")
>>> import importme
>>> CLASS HELLO
Edit: The reason: The class creation process involves executing the body of the class.
The class body is executed (approximately) as
exec(body, globals(), namespace)
. [...] Once the class namespace has been populated by executing the class body, the class object is created by callingmetaclass(name, bases, namespace, **kwds)
.
https://docs.python.org/3/reference/datamodel.html?highlight=metaclass#executing-the-class-body
My original answer text. You can ignore it - I'm just leaving it in because mirek's comment was a direct response to it:
Class attributes are evaluated on import. The answer to when or exactly how that happens, resides within the depths of python's import system.
Consider these two ways of defining the success_url. The first is commented out, the second is the function:
class NewJobCBV(LoginRequiredMixin, CreateView):
template_name = 'company/job.html'
form_class = newJobForm
# success_url = reverse_lazy('newJob')
def get_success_url(self, **kwargs):
return reverse("newJob")
@CoffeeBasedLifeform : you are right, class attributes are evaluated on import, I checked after reading your answer. So,
- If we are using
success_url
we have to usereverse_lazy()
. - If we are reversing inside a function we can use
reverse()
.
Now it is crystal clear.
Thanks CoffeeBasedLifeform :)