I have a doubt and which is better reverse
or reverse_lazy
?, I saw somewhere that it was better reverse_lazy
and that it is better to use it reverse_lazy
in everything, because it is a function that is executed at runtime and should not be validated during Django loading. and that reverse
there is a possibility that it is not validated in execution, something like that....
I mean that for example instead of using in the method get_success_url
, reverse
it is better to use reverse_lazy
since it is better. (As explained above.)
def get_success_url(self):
return reverse_lazy('pages:pages')
Practically that reverse_lazy
almost completely replaces reverse
(well not so exaggerated) Well I hope I make myself understood.
But I still can't understand very well what is the difference between reverse
and reverse_lazy
and which is better. Also, how exactly does each one work?
Thanks in advance for your answers!
As part of the Django application, somewhere there must be a file that the documentation calls "URLConf", but in your case it will have whatever name you decide to give it (usually it will be called something
urls.py
like that, and there can be several of these, but there will be one "master" that imports the rest).This file contains a variable
urlpatterns
that is a list of mappings between urls and the methods that must be executed to serve those urls. For example, things like:When Django has read that file, it knows that a request to the route
articles/2019/
must be converted to an execution ofviews.year_archive()
, passing it 2019 as a parameter. It also associates the name "archive" with that view.Well, when you use
reverse("archive", kwargs={"year": 2019})
you are asking Django to tell you what would be the route that would cause the execution of the view "archive" with parameteryear=2019
(it would be the route"/articles/2019/"
).If when you run
reverse()
Django it had already read yoururls.py
, it will already have the information to respond to you, since it already knows that the name "archive" has been associated with the path/articles/<int:year>/
.But since in Python everything is dynamic, it is possible that at the moment you execute
reverse("archive", ...)
the fileurls.py
it has not yet been loaded (although it will be loaded later, it depends on the order in which theimport
, theinclude
, etc. are done). Then the attempt to usereverse("archive", ...)
will fail as the name"archive"
is not yet associated with any route.That's when it
reverse_lazy()
can be useful. When you usereverse()
the result it is a string (the reverse URL you wanted), but when you usereverse_lazy()
the result it is a function, which will be called at the end, once all the config files have been loaded and the response is about to be sent to the client . By then the name will be known"archive"
and the functionreverse_lazy()
you can usereverse()
to generate your response.I don't have much experience with Django and I can't tell you which of the two is "better". From what I've read it seems that people in general use
reverse()
and if they run into an error, they change it toreverse_lazy()
. I'm not sure why it's not better to use directlyreverse_lazy()
everywhere to save yourself trouble, except for the fact that the latter involves an extra call to another function, which may have a bit of a performance hit, but I think this effect is negligible . The fact is that apparentlyreverse_lazy()
it is used very little, although I could not tell you why.