2012-06-20 11 views
0

以前我一直在研究幾種解決方案,如何用電子郵件地址而不是用戶名註冊。我發現的所有資源都着眼於創建自定義後端和滾動註冊頁面。雖然這適用於我,但我無法找到解釋如何處理登錄屏幕的單一解決方案。Django中的登錄屏幕 - 子類化或創建表單模板?

我用電子郵件授權

註冊的所有方法首先:我的電子郵件地址,並創建它的一個哈希作爲用戶名,並儲存起來。

登錄:我再次獲取電子郵件地址並創建它的散列並嘗試使用 查找具有相同散列的用戶名。

它的代碼是如何做到:

設置

AUTHENTICATION_BACKENDS = ('MyApp.auth_backends.CustomUserModelBackend',) 
CUSTOM_USER_MODEL = 'MyApp.CustomUser' 

models.py

class CustomUser(User): 
    timezone = models.CharField(max_length=50, default='Europe/London') 
    objects = UserManager() 

我已經定製了registrat離子這樣的:

View.py

def register_page(request): 
    if request.method == 'POST': 
     form = RegistrationForm(request.POST) 
     if form.is_valid(): 
      user = CustomUser.objects.create_user(
       username=md5(form.cleaned_data['email']).digest().encode('base64')[:-1], 
       password=form.cleaned_data['password2'], 
       email=form.cleaned_data['email'] 
      ) 

      return HttpResponseRedirect('/register/success/') 
    else: 
     form = RegistrationForm() 
    variables = RequestContext(request, {'form':form}) 
    return render_to_response('registration/register.html', variables) 

auth_backends.CustomUserModelBackend:

計算給定的電子郵件地址的哈希以找到相關的用戶名。

class CustomUserModelBackend(ModelBackend): 
    def authenticate(self, username=None, password=None): 
     try: 
      # The parameter Username is here really just the email address, I get 
      # the hash for the email parameter and try to find the user. 

      hash_user = md5(username).digest().encode('base64')[:-1], 
      user = self.user_class.objects.get(username=hash_user) 
      if user.check_password(password): 
       return user 
     except self.user_class.DoesNotExist: 
      return None 

    def get_user(self, user_id): 
     try: 
      return self.user_class.objects.get(pk=user_id) 
     except self.user_class.DoesNotExist: 
      return None 

    @property 
    def user_class(self): 
     if not hasattr(self, '_user_class'): 
      self._user_class = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2)) 
      if not self._user_class: 
       raise ImproperlyConfigured('Could not get custom user model') 
     return self._user_class 

現在我堅持的登錄界面。

我已經這樣做了,但我得到了重定向回登錄屏幕沒有得到任何錯誤顯示。

url.py

(r'^login/$', 'django.contrib.auth.views.login'), 

註冊/ login.html的

{% extends "base.html" %} 
{% block title %}user login{% endblock %} 
{% block head %}User login{% endblock %} 
{% block content %}{% if form.errors %} 
    <p>Your email and password didn't match</p> 
{% endif %} 
    <form action="." method="post"> 
     <p> 
      <label for="id_username">Email:</label>{{ form.username }} 
     </p> 
     <p> 
      <label for="id_password">Password:</label>{{ form.password }} 
     </p> 
     {% csrf_token %} 
     <input type="hidden" name="next" value="/" /> 
     <input type="submit" value="login" /> 
    </form> 
{% endblock %} 

我知道這個解決方案已經有問題的,因爲我需要一個電子郵件輸入 「用戶名」,而不是charfield。

1)我需要做些什麼來重寫字段類型?

2)我仍然無法登錄,它表示用戶名不符合密碼。

我調試它在驗證和它沒有找到用戶

  hash_user = md5(username).digest().encode('base64')[:-1], 
      user = self.user_class.objects.get(username=hash_user) 

是不相同的電子郵件地址的哈希總是一樣的?我可能會錯過什麼?

更新:

我可以清楚地看到的哈希碼被保存在數據庫中的用戶名,我可以看到如何進行身份驗證user = self.user_class.objects.get(username=hash_user)內的哈希碼是相同的值在數據庫中。但它仍然不檢索用戶。爲什麼?

enter image description here enter image description here

更新2:

我發現這個問題。我有一個逗號錯誤,並把哈希變成了一個元組。哦,親愛的

這是正確的,工作原理:

hash_user = md5(username).digest().encode('base64')[:-1] 
user = self.user_class.objects.get(username=hash_user) 

在這裏,我們現在有完整的解決方案。就一件事。

有人能幫我1)嗎?我該如何重寫用戶名charfield?

回答

1
+0

啊,我明白了。謝謝克里斯。你會說這是一個好主意,以鏡像django.contrib.auth.forms.AuthenticationForm,但使用電子郵件字段,而不是CharField? – Houman

+0

對於「鏡像」,我的意思是像複製和粘貼作爲一種新形式。 :) – Houman

+0

我已經發現自己在複製,粘貼和編輯django源代碼的情況下,我不能只是將其覆蓋到我的口味。例如,基於類的視圖中的某些方法需要完全相同的行爲,減去一行。 –