Reputation: 13
I am looking to add email account verification in Django and found a nice open source code that I can adopt. But there is one line which I'm not familiar with.
Why does the function "password_reset_confirm" need to return two **kwargs in separate brackets and how each of them is used in the class "PasswordResetConfirm"?
This question might be related to Python rather than Django. But anyway, thank you for your help!
urls.py
url(r"^password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-
z]{1,13}-[0-9A-Za-z]{1,20})/$",views.password_reset_confirm, name="reset-
password-confirm",)
views.py
from django.contrib.auth import views as django_views
class PasswordResetConfirm(django_views.PasswordResetConfirmView):
template_name = "account/password_reset_from_key.html"
success_url = reverse_lazy("account:reset-password-complete")
token = None
uidb64 = None
def form_valid(self, form):
response = super(PasswordResetConfirm, self).form_valid(form)
account_events.customer_password_reset_event(user=self.user)
return response
def password_reset_confirm(request, uidb64=None, token=None):
kwargs = {
"template_name": "account/password_reset_from_key.html",
"success_url": reverse_lazy("account:reset-password-complete"),
"token": token,
"uidb64": uidb64,
}
return PasswordResetConfirm.as_view(**kwargs)(request, **kwargs)
Upvotes: 1
Views: 145
Reputation: 20569
First variable (uidb64
) is just base64-encoded ID of user, extracted from database. By this field Django can determine which user is requesting password reset.
Second variable (token
) is an actual reset token that is used to verify user request. User can get this token only from email that was sent to him, so this verifies that user has access to provided email address, so we can proceed with password reset.
Why we can't use token
alone? There are 2 reasons for that
SECRET_KEY
stored in database, current user password hash and time of generating this token. After that, only time can be extracted from token and by fetching user data together with SECRET_KEY
from settings, Django can verify that password reset token is valid for specified user. Time of token generation is here, so every token can expire after some time.As for passing kwargs twice, here is quick explanation by example:
In python, you can return function from calling any other function or method (most often those kind of functions are called factories):
def some_factory():
def some_function():
print('abc')
return some_function
my_function = some_factory()
In this example, print won't be called as we are not executing some_function
, some_factory
returns it, so we can use it later:
my_function()
Now this print will be called and we will see abc
in console output. But instead of assigning returned function to some variable or passing it somewhere, you can call it immediately:
some_factory()()
This is where the second parentheses come from. Of course both functions can take some arguments, then you will provide arguments for factory inside first pair of parentheses and arguments to some_function
in second.
Back to your example, it is actually invalid, you shouldn't pass full kwargs to as_view
in PasswordResetConfirm
. It should take only first two (template_name
and success_url
). Actual view (second parentheses) should take other two (token
and uidb64
).
2nd thing that is wrong in your code is that you're calling as_view
on every request. It is designed to be called only once, when creating this view. Instead of wrapping it in separate function, use it directly in your urls.py
:
url(
r"^password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$",
PasswordResetConfirm.as_view(
template_name="account/password_reset_from_key.html"
success_url=reverse_lazy("account:reset-password-complete"),
), name="reset-password-confirm",
)
Upvotes: 1