Почему django 1.6 устанавливает "form" в "none" в представлении contrib.auth.views.password_reset_confirm?
Я использую django 1.6 и django-registration 1.0.
Мне пришлось исправлять URL-адреса при регистрации django, так как они не выпустили обновление по состоянию на 19 февраля 2014 года.
Все URL / представления для сброса пароля работали, кроме password_reset_confirm.
В моем основном файле urls.py у меня есть это:
url(r'^accounts/', include('registration.backends.simple.urls')),
На регистрации /Backends/Simple/urls.py У меня есть это:
from django.conf.urls import include
from django.conf.urls import patterns
from django.conf.urls import url
from django.views.generic.base import TemplateView
from registration.backends.simple.views import RegistrationView
urlpatterns = patterns('',
url(r'^register/$',
RegistrationView.as_view(),
name='registration_register'),
url(r'^register/closed/$',
TemplateView.as_view(template_name='registration/registration_closed.html'),
name='registration_disallowed'),
(r'', include('registration.auth_urls')),
)
from django.contrib.auth import views as auth_views
# THIS IS A PATCH added by me !!!
urlpatterns = patterns('',
# override the default urls
url(r'^password/change/$',
auth_views.password_change,
name='password_change'),
url(r'^password/change/done/$',
auth_views.password_change_done,
name='password_change_done'),
url(r'^password/reset/$',
auth_views.password_reset,
name='password_reset'),
url(r'^password/reset/done/$',
auth_views.password_reset_done,
name='password_reset_done'),
url(r'^password/reset/complete/$',
auth_views.password_reset_complete,
name='password_reset_complete'),
url(r'^password/reset/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
auth_views.password_reset_confirm,
name='password_reset_confirm'),
# and now add the registration urls
url(r'', include('registration.backends.default.urls')),
)
Django1.6 django / contrib / auth / views.py имеет функцию для password_reset_confirm:
# Doesn't need csrf_protect since no-one can guess the URL
@sensitive_post_parameters()
@never_cache
def password_reset_confirm(request, uidb64=None, token=None,
template_name='registration/password_reset_confirm.html',
token_generator=default_token_generator,
set_password_form=SetPasswordForm,
post_reset_redirect=None,
current_app=None, extra_context=None):
"""
View that checks the hash in a password reset link and presents a
form for entering a new password.
"""
UserModel = get_user_model()
assert uidb64 is not None and token is not None # checked by URLconf
if post_reset_redirect is None:
post_reset_redirect = reverse('password_reset_complete')
else:
post_reset_redirect = resolve_url(post_reset_redirect)
try:
uid = urlsafe_base64_decode(uidb64)
user = UserModel._default_manager.get(pk=uid)
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
user = None
if user is not None and token_generator.check_token(user, token):
validlink = True
if request.method == 'POST':
form = set_password_form(user, request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(post_reset_redirect)
else:
form = set_password_form(None)
else:
validlink = False
form = None
context = {
'form': form,
'validlink': validlink,
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
Таким образом, либо token_generator.check_token (user, token) возвращает False, либо user == None.
Самая большая боль в том, что это происходит (как мне кажется) только случайно. Так что отладка - это боль. Иногда работает ({{ form }}
предоставляет входы) и часто это не удается ({{ form }}
выводит "None" вместо входной разметки)
Любая помощь приветствуется.
1 ответ
По какой-то причине token_generator.check_token(user, token)
определяет, что метка времени / uid была подделана. Это означает, что новый токен должен быть сгенерирован.
Из шаблона я собираюсь обнаружить, что {{ form }}
"Нет". Если это так, я поставлю ссылку, которая перезапустит весь процесс.
{% if form != None %}
<div class="modal-body">
<p>Type in a new password. Try not to forget this one!</p>
{{ form }}
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary"><span>Continue</span></button>
</div>
{% else %}
<div class="modal-body">
<p>This link has expired. You'll need to click "Reset Password" again.</p>
<p><a class="btn btn-primary" href="{% url 'auth_password_reset' %}">Reset Password</a></p>
</div>
{% endif %}
Это важно, потому что django-bootstrap-form захлебнется и выдаст ошибку 500, если у вас ее нет.