以前我一直在研究幾種解決方案,如何用電子郵件地址而不是用戶名註冊。我發現的所有資源都着眼於創建自定義後端和滾動註冊頁面。雖然這適用於我,但我無法找到解釋如何處理登錄屏幕的單一解決方案。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)
內的哈希碼是相同的值在數據庫中。但它仍然不檢索用戶。爲什麼?
更新2:
我發現這個問題。我有一個逗號錯誤,並把哈希變成了一個元組。哦,親愛的
這是正確的,工作原理:
hash_user = md5(username).digest().encode('base64')[:-1]
user = self.user_class.objects.get(username=hash_user)
在這裏,我們現在有完整的解決方案。就一件事。
有人能幫我1)嗎?我該如何重寫用戶名charfield?
啊,我明白了。謝謝克里斯。你會說這是一個好主意,以鏡像django.contrib.auth.forms.AuthenticationForm,但使用電子郵件字段,而不是CharField? – Houman
對於「鏡像」,我的意思是像複製和粘貼作爲一種新形式。 :) – Houman
我已經發現自己在複製,粘貼和編輯django源代碼的情況下,我不能只是將其覆蓋到我的口味。例如,基於類的視圖中的某些方法需要完全相同的行爲,減去一行。 –