2015-11-19 2 views
1

Я хочу сбросить пароль в приложении django, посетив определенный URL-адрес и отправив электронное письмо методом POST. Это потому, что я хочу использовать его в Android-приложении, которое будет иметь свою собственную форму. Итак, я думал, что могу создать настраиваемую форму сброса пароля, а затем сохранить его, но он не работает.отправка пользовательской формы сброса пароля

from django.contrib.auth.forms import PasswordResetForm 

class Custom_password_reset_form(PasswordResetForm): 
    def __init__(self, email, **kwargs): 
     super(Custom_password_reset_form, self).__init__(**kwargs) 
     self.email = forms.EmailField(initial=email, max_length=254) 


def mobile_password_reset(request): 
    """Sends mail with password reset link.""" 
    email = request.POST.get('email') 
    my_form = Custom_password_reset_form(email) 

    if my_form.is_valid(): 
     print 'valid' 
     my_form.save() 
    else: 
     print 'not valid' 
     print my_form._errors 
    return render(...) 

Валидация всегда терпит неудачу, давая пустой список my_form._errors. Что мне здесь не хватает? Или, может быть, есть лучший способ сделать это?

Правильный код:

Пользовательский класс не является необходимым, и должны быть удалены. Метод сброса пароля должен выглядеть следующим образом:

def mobile_password_reset(request): 
    """Sends mail with password reset link.""" 
    my_form = PasswordResetForm(request.POST) 
    if my_form.is_valid(): 
     my_form.save() 
     return JsonResponse({'success': True}) 
    else: 
     return JsonResponse({'success': False}) 

Важно отметить, что без django.contrib.sites приложение добавлено в настройки, my_form.save() не будет работать. Это также можно было бы исправить добавлением этого аргумента: my_form.save(request=request).

ответ

2

A форма needs to be bound to data to be valid. Вы передаете аргумент электронной почты, но не data, поэтому форма всегда будет несвязана. Для несвязанных форм is_valid() возвращает False, но ошибок нет.

Я не понимаю, для чего требуется ваша пользовательская форма. Если email находится в request.POST, почему бы не просто пройти request.POST к обычным PasswordRestForm?

my_form = PasswordResetForm(request.POST) 
0

Вы можете сделать это, переопределив модуль auth django. Добавить следующие ссылки в вашем urls.py

url(r'^password_reset/$', PasswordReset.as_view(is_admin_site=True), 
    {'is_admin_site': 'True'}), 

После этого добавьте следующие мнения

class PasswordReset(RedirectView): 
is_admin_site = False 
template_name = 'forget_password.html' 
email_template_name = 'password_reset_email.html' 
subject_template_name = 'password_reset_subject.html' 
token_generator = default_token_generator 
post_reset_redirect = None 
from_email = None, 
current_app = None, 
extra_context = None 

def get(self, request, *args, **kwargs): 

    form = YourCustomPasswordResetForm() 
    context = { 
     'form': form, 
    } 
    if self.extra_context is not None: 
     context.update(self.extra_context) 
    return TemplateResponse(request, self.template_name, context, 
          current_app=self.current_app) 

def post(self, request, *args, **kwargs): 
    form = YourCustomPasswordResetForm(request.POST) 
    if form.is_valid(): 
     if self.from_email is not None: 
      from_email = 'From Email' 
     opts = { 
      'use_https': request.is_secure(), 
      'token_generator': self.token_generator, 
      'from_email': self.from_email, 
      'email_template_name': self.email_template_name, 
      'subject_template_name': self.subject_template_name, 
      'request': request, 
     } 
     if self.is_admin_site: 
      opts = dict(opts, domain_override=request.get_host()) 
     form.save(**opts) 
     return HttpResponseRedirect(self.post_reset_redirect) 
    context = { 
     'form': form, 
    } 
    if self.extra_context is not None: 
     context.update(self.extra_context) 
    return TemplateResponse(request, self.template_name, context, 
          current_app=self.current_app) 

В вас формах, добавьте вы формируете и добавить folloing метод сохранения в нем.

def save(self, domain_override=None, 
     subject_template_name='registration/password_reset_subject.txt', 
     email_template_name='registration/password_reset_email.html', 
     use_https=False, token_generator=default_token_generator, 
     from_email=None, request=None): 
    """ 
    Generates a one-use only link for resetting password and sends to the 
    user. 
    """ 
    from_email = 'From Email' 
    from django.core.mail import send_mail 

    user = User.objects.get(username=request.POST['username']) 
    if not domain_override: 
     current_site = get_current_site(request) 
     site_name = current_site.name 
     domain = current_site.domain 
    else: 
     site_name = domain = domain_override 
     c = { 
      'email': user.email, 
      'domain': domain, 
      'site_name': site_name, 
      'uid': int_to_base36(user.id), 
      'user': user, 
      'token': token_generator.make_token(user), 
      'protocol': use_https and 'https' or 'http', 
     } 
    subject = loader.render_to_string(subject_template_name, c) 
    # Email subject *must not* contain newlines 
    subject = ''.join(subject.splitlines()) 
    email = loader.render_to_string(email_template_name, c) 
    send_mail(subject, email, from_email, [user.email]) 

Когда вы отправите эту форму, пользователь получит электронную почту со ссылкой, содержащей токен. Эта ссылка может использоваться только один раз.

+0

Я не проверял ваш ответ, но, похоже, он слишком тяжел для моей проблемы. – jligeza

Смежные вопросы