Reputation: 99
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
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