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 calling metaclass(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,

  1. If we are using success_url we have to use reverse_lazy().
  2. If we are reversing inside a function we can use reverse().

Now it is crystal clear.

Thanks CoffeeBasedLifeform :)