2015-11-19 53 views
1

我想通過訪問某個url並通過POST方法傳遞電子郵件來重置django應用中的密碼。那是因爲我想在一個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

表格needs to be bound to data to be valid。您正在傳遞電子郵件參數,但沒有data,因此表單將始終處於未綁定狀態。對於未綁定的表單,is_valid()返回False,但沒有錯誤。

我不明白你的自定義窗體需要什麼。如果emailrequest.POST,爲什麼不通過request.POST到正規PasswordRestForm

my_form = PasswordResetForm(request.POST) 
0

你可以通過覆蓋django的auth模塊來做到這一點。 添加以下網址在你的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