У меня есть приложение django, которое использует Django Rest Framework.Сочетание обычных Django-представлений с Django Rest Framework View
Я пытаюсь создать пользователю сброса пароля потока с помощью формы на основе Django класса View. Для этого я определил URL, как:
url(r'^reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
views.PasswordResetConfirmView.as_view(), name='reset_confirm'),
url(r'^reset/$', views.ResetPasswordRequestView.as_view(), name='reset')
Но проблема в том, что, когда я пытаюсь посетить URL сброса, он показывает следующее сообщение об ошибке.
Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<type 'NoneType'>`
Я не уверен, разрешено ли смешивание представлений DRF и просмотров Django.
Что я делаю неправильно? Каким должен быть наилучший подход для создания потока сброса пароля с использованием только DRF.
Редактировать, код ResetPasswordRequestView
class ResetPasswordRequestView(FormView):
template_name = "users/password_reset_template.html"
form_class = PasswordResetRequestForm
success_url = "#"
@staticmethod
def validate_email_address(email):
try:
validate_email(email)
return True
except ValidationError:
return False
# default method to handle post requests
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
if self.validate_email_address(email) is True:
try:
user_profile = Profile.objects.get(email=email)
except Profile.DoesNotExist:
user_profile = None
if user_profile:
# send mail here
subject_template_name = 'registration/password_reset_subject.txt'
email_template_name = 'registration/password_reset_email.html'
subject = loader.render_to_string(subject_template_name, message)
# subject should not contain newlines
subject = ''.join(subject.splitlines())
email = loader.render_to_string(email_template_name, message)
send_mail(subject, email, settings.DEFAULT_FROM_EMAIL, [user_profile.email], fail_silently=False)
result = self.form_valid(form)
messages.success(request, 'Email has been sent to ' + email +
"'s email address. Please check its inbox to "
"continue resetting password.")
return result
result = self.form_invalid(form)
messages.error(request, 'This username does not exist in the system.')
return result
messages.error(request, 'Invalid Input')
return self.form_invalid(form)
Код для PasswordResetConfirmView
class PasswordResetConfirmView(FormView):
template_name = 'users/change_password.html'
success_url = "/"
form_class = ChangePasswordForm
def post(self, request, uidb64=None, token=None, *args, **kwargs):
form = self.form_class(request.POST)
assert uidb64 is not None and token is not None
try:
uid = urlsafe_base64_decode(uidb64)
user_profile = Profile.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, Profile.DoesNotExist):
user_profile = None
if user_profile is not None and default_token_generator.check_token(user_profile, token):
if form.is_valid():
new_password = form.cleaned_data['password']
user_profile.set_password(new_password)
user_profile.save()
messages.success(request, 'Password has been reset.')
return self.form_valid(form)
else:
messages.error(request, 'Password reset has not been unsuccessful.')
return self.form_invalid(form)
else:
messages.error(request, 'The reset password link is no longer valid.')
return self.form_invalid(form)
StackTrace показывает следующее, изменили путь питона здесь (это правильно на моем компьютере)
Traceback:
File "/[base path here]/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/[base path here]/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
58. return view_func(*args, **kwargs)
File "/[base path here]/local/lib/python2.7/site-packages/django/views/generic/base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "/[base path here]/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
468. self.response = self.finalize_response(request, response, *args, **kwargs)
File "/[base path here]/local/lib/python2.7/site-packages/rest_framework/views.py" in finalize_response
396. % type(response)
Exception Type: AssertionError at /user/reset/
Exception Value: Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<type 'NoneType'>`
urls.py
from django.conf.urls import url
from users import views
urlpatterns = [
url(r'^signup/$', views.register),
url(r'^check-username/$', views.check_username),
url(r'^change-password/$', views.change_password),
url(r'^interests/$', views.get_all_interests),
url(r'^signin/$', 'rest_framework_jwt.views.obtain_jwt_token'),
url(r'^verify-token/$', 'rest_framework_jwt.views.verify_jwt_token'),
url(r'^(?P<user_id>[0-9]{1,6})/$', views.generate_feed),
url(r'^community/(?P<community_id>[0-9]{1,6})/'
r'(?P<user_id>[0-9]{1,6})/$', views.community_feed),
url(r'^(?P<username>[A-Za-z_\.]{1,20})/$', views.user_profile),
# url's for reset password
url(r'^reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
views.PasswordResetConfirmView.as_view(), name='reset_confirm'),
url(r'^reset/$', views.ResetPasswordRequestView.as_view(), name='reset'),
]
Редактировать: Он отлично работает, когда я устанавливаю URL-адреса перезагрузки перед другими URL-адресами, но до сих пор не знаю, как и почему?
Проблема заключается в коде для 'views.ResetPasswordRequestView'. Можете ли вы опубликовать этот класс? – joerick
@joerick добавлен код просмотра – ofnowhere
@ofnowhereland Миксин двух «парадигм» полностью разрешен и действителен! –