回答
這是我們所做的。這不是一個「完整的」解決方案,但它可以滿足你的要求。
from django import forms
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
class Meta:
model = User
exclude = ('email',)
username = forms.EmailField(max_length=64,
help_text="The person's email address.")
def clean_email(self):
email = self.cleaned_data['username']
return email
class UserAdmin(UserAdmin):
form = UserForm
list_display = ('email', 'first_name', 'last_name', 'is_staff')
list_filter = ('is_staff',)
search_fields = ('email',)
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
有幫助。謝謝。 – 2009-12-26 20:34:31
適合我。儘管我可以看到這會讓未來的維護者感到困惑。 – 2010-02-02 10:10:39
我應該在哪裏放這個代碼? – 2016-07-29 15:08:48
對於任何人想要做到這一點,我建議考慮看看django-email-as-username這是一個非常全面的解決方案,包括修補管理員和createsuperuser
管理命令等等。
編輯:從Django 1.5開始,您應該考慮使用custom user model而不是django-email-as-username。
如果您決定自定義用戶模型是最佳選擇,則可能需要檢查[本教程](http://www.caktusgroup.com/blog/2013/08/07/migrating-custom-user-model- django /)在caktus組博客上,它類似於[本示例](https://docs.djangoproject.com/en/1.7/topics/auth/customizing/#a-full-example)在Django文檔中給出,但要小心生產環境所需的一些細節(例如權限)。 – gaboroncancio 2015-01-22 22:55:16
對於Django 1.5及以上版本,[django-custom-user](https://github.com/jcugat/django-custom-user)應用程序包含一個實現此功能的自定義用戶模型。 – 2015-03-07 02:10:54
最新的Django登記的版本允許一些漂亮的自定義和可能做的工作 - 在這裏文檔https://bitbucket.org/ubernostrum/django-registration/src/fad7080fe769/docs/backend-api.rst
最簡單的方法是查找基於登錄查看電子郵件的用戶名。這樣,你可以別的先不談一切:
from django.contrib.auth import authenticate, login as auth_login
def _is_valid_email(email):
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
try:
validate_email(email)
return True
except ValidationError:
return False
def login(request):
next = request.GET.get('next', '/')
if request.method == 'POST':
username = request.POST['username'].lower() # case insensitivity
password = request.POST['password']
if _is_valid_email(username):
try:
username = User.objects.filter(email=username).values_list('username', flat=True)
except User.DoesNotExist:
username = None
kwargs = {'username': username, 'password': password}
user = authenticate(**kwargs)
if user is not None:
if user.is_active:
auth_login(request, user)
return redirect(next or '/')
else:
messages.info(request, "<stvrong>Error</strong> User account has not been activated..")
else:
messages.info(request, "<strong>Error</strong> Username or password was incorrect.")
return render_to_response('accounts/login.html', {}, context_instance=RequestContext(request))
在模板中設置下一個變量相應,即
<form method="post" class="form-login" action="{% url 'login' %}?next={{ request.GET.next }}" accept-charset="UTF-8">
,給您的用戶名/密碼輸入正確的名稱,即用戶名,密碼。
UPDATE:
另外,如果該_is_valid_email(電子郵件):調用可以與如果用戶名換成 '@'。這樣你可以放棄_is_valid_email函數。這真的取決於你如何定義你的用戶名。如果您在用戶名中允許輸入「@」字符,它將不起作用。
此代碼有問題,因爲用戶名還可以有'@'符號,所以如果存在'@',則不需要電子郵件。 – MrKsn 2014-10-06 18:41:31
真的取決於你,我不允許用戶名擁有@符號。如果你這樣做,你可以添加另一個過濾器查詢來通過用戶名搜索用戶對象。 PS。用戶名也可以是電子郵件,所以你必須小心設計你的用戶管理。 – radtek 2014-10-06 23:10:21
另外檢查出來,從django.core.validators導入validate_email。您可以嘗試使用validate_email('[email protected]')除ValidationError塊外的嘗試。它可能仍然是錯誤的,這取決於你的應用程序。 – radtek 2014-10-06 23:15:06
下面是做這件事,使雙方的用戶名和電子郵件接受:
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.forms import ValidationError
class EmailAuthenticationForm(AuthenticationForm):
def clean_username(self):
username = self.data['username']
if '@' in username:
try:
username = User.objects.get(email=username).username
except ObjectDoesNotExist:
raise ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
params={'username':self.username_field.verbose_name},
)
return username
不知道是否有一些設置來設置默認的認證形式,但你也可以重寫URL中urls.py
url(r'^accounts/login/$', 'django.contrib.auth.views.login', { 'authentication_form': EmailAuthenticationForm }, name='login'),
提高ValidationError將防止在提交無效電子郵件時出現500錯誤。對於「invalid_login」使用超級定義可以使錯誤消息保持不明確(與找到該電子郵件的特定「未找到用戶」),防止電子郵件地址是否爲您的服務上的帳戶註冊而出現泄漏。如果這些信息在您的體系結構中不安全,那麼提供更多信息錯誤消息可能會更友好。
的Django現在提供了管理和形式的擴展認證系統的完整的例子:https://docs.djangoproject.com/en/stable/topics/auth/customizing/#a-full-example
基本上你可以複製/粘貼和適應(我不需要在我的情況下date_of_birth
)。
它實際上是從Django 1.5開始提供的,並且至今仍然可用(django 1.7)。
其他替代方案對我來說看起來太複雜了,所以我寫了一個代碼片段,允許使用用戶名,電子郵件或兩者進行身份驗證,並啓用或禁用區分大小寫。我把它上傳到pip,作爲django-dual-authentication。
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from django.conf import settings
###################################
""" DEFAULT SETTINGS + ALIAS """
###################################
try:
am = settings.AUTHENTICATION_METHOD
except:
am = 'both'
try:
cs = settings.AUTHENTICATION_CASE_SENSITIVE
except:
cs = 'both'
#####################
""" EXCEPTIONS """
#####################
VALID_AM = ['username', 'email', 'both']
VALID_CS = ['username', 'email', 'both', 'none']
if (am not in VALID_AM):
raise Exception("Invalid value for AUTHENTICATION_METHOD in project "
"settings. Use 'username','email', or 'both'.")
if (cs not in VALID_CS):
raise Exception("Invalid value for AUTHENTICATION_CASE_SENSITIVE in project "
"settings. Use 'username','email', 'both' or 'none'.")
############################
""" OVERRIDDEN METHODS """
############################
class DualAuthentication(ModelBackend):
"""
This is a ModelBacked that allows authentication
with either a username or an email address.
"""
def authenticate(self, username=None, password=None):
UserModel = get_user_model()
try:
if ((am == 'email') or (am == 'both')):
if ((cs == 'email') or cs == 'both'):
kwargs = {'email': username}
else:
kwargs = {'email__iexact': username}
user = UserModel.objects.get(**kwargs)
else:
raise
except:
if ((am == 'username') or (am == 'both')):
if ((cs == 'username') or cs == 'both'):
kwargs = {'username': username}
else:
kwargs = {'username__iexact': username}
user = UserModel.objects.get(**kwargs)
finally:
try:
if user.check_password(password):
return user
except:
# Run the default password hasher once to reduce the timing
# difference between an existing and a non-existing user.
UserModel().set_password(password)
return None
def get_user(self, username):
UserModel = get_user_model()
try:
return UserModel.objects.get(pk=username)
except UserModel.DoesNotExist:
return None
如果要擴展用戶模型,則必須實現自定義用戶模型。
下面是Django 1.8的示例。 Django 1.7將需要更多的工作,主要是更改默認表單(只需看看UserChangeForm
& UserCreationForm
在django.contrib.auth.forms
-這就是1.7中你需要的)。
user_manager.py:
from django.contrib.auth.models import BaseUserManager
from django.utils import timezone
class SiteUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
today = timezone.now()
if not email:
raise ValueError('The given email address must be set')
email = SiteUserManager.normalize_email(email)
user = self.model(email=email,
is_staff=False, is_active=True, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password, **extra_fields):
u = self.create_user(email, password, **extra_fields)
u.is_staff = True
u.is_active = True
u.is_superuser = True
u.save(using=self._db)
return u
models.py:
from mainsite.user_manager import SiteUserManager
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
class SiteUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, blank=False)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
objects = SiteUserManager()
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
forms.py:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
from mainsite.models import SiteUser
class MyUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = SiteUser
fields = ("email",)
class MyUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = SiteUser
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
add_form = MyUserCreationForm
fieldsets = (
(None, {'fields': ('email', 'password',)}),
('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser',)}),
('Groups', {'fields': ('groups', 'user_permissions',)}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2')}
),
)
list_display = ('email',)
list_filter = ('is_active',)
search_fields = ('email',)
ordering = ('email',)
admin.site.register(SiteUser, MyUserAdmin)
settings.py:
AUTH_USER_MODEL = 'mainsite.SiteUser'
我認爲最快速的方法是創建一個從UserCreateForm
繼承的表單,然後用forms.EmailField
覆蓋username
字段。然後,對於每個新的註冊用戶,他們需要使用他們的電子郵件地址進行註冊。
例如:
urls.py
...
urlpatterns += url(r'^signon/$', SignonView.as_view(), name="signon")
views.py
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django import forms
class UserSignonForm(UserCreationForm):
username = forms.EmailField()
class SignonView(CreateView):
template_name = "registration/signon.html"
model = User
form_class = UserSignonForm
signon.html
...
<form action="#" method="post">
...
<input type="email" name="username" />
...
</form>
...
不知道人們是否試圖完成這項工作,但我發現很好(和乾淨)的方式只要求電子郵件,然後在保存前將用戶名設置爲視圖中的電子郵件。
我的窗體只需要電子郵件地址和密碼:
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('email', 'password')
然後在我看來,我想補充以下邏輯:
if user_form.is_valid():
# Save the user's form data to a user object without committing.
user = user_form.save(commit=False)
user.set_password(user.password)
#Set username of user as the email
user.username = user.email
#commit
user.save()
if user_form.is_valid():
# Save the user's form data to a user object without committing.
user = user_form.save(commit=False)
user.set_password(user.password)
#Set username of user as the email
user.username = user.email
#commit
user.save()
完美......工作的Django 1.11.4
- 1. Django在forms.py中驗證電子郵件地址和用戶名
- 2. Django電子郵件地址
- 3. 作爲登錄用戶名的電子郵件地址 - PHP&Zend_Auth?
- 4. 如何獲取電子郵件地址作爲用戶名每
- 5. 命令行SFTP:電子郵件地址作爲用戶名
- 6. 接受用戶名或電子郵件與登錄的Django allauth
- 7. 如何用Regex在電子郵件地址中接受點?
- 8. 在Django中用電子郵件作爲用戶名
- 9. 在Tank Auth中使用電子郵件地址作爲用戶名
- 10. 如何在Joomla中使用電子郵件地址作爲用戶名?
- 11. 將select2限制爲只接受電子郵件地址
- 12. 電子郵件地址在Sitecore中的用戶名稱
- 13. 使WordPress用戶名成爲電子郵件地址
- 14. authlogic電子郵件作爲用戶名
- 15. PHPMailer使用SMTP用戶名作爲發件人電子郵件地址
- 16. Powerbi用戶的電子郵件地址
- 17. 登錄用的用戶名或電子郵件地址在PHP
- 18. 接受ASP.NET中的電子郵件地址
- 19. 的iOS電子郵件地址驗證不接受。在
- 20. 使用電子郵件作爲用戶名與Django的註冊
- 21. 的Django 1.8 EmailField現在接受無效的電子郵件地址
- 22. Asp.Net Web應用程序將不接受電子郵件作爲用戶名
- 23. 登錄名 - 用戶名和電子郵件地址
- 24. 在電子郵件地址
- 25. Django管理員:允許電子郵件作爲用戶名?
- 26. 設置電子郵件作爲用戶名的Django 1.5
- 27. Django更新用戶電子郵件地址
- 28. 詢問用戶的姓名和電子郵件地址作爲輸出
- 29. 用用戶名或電子郵件地址登錄
- 30. 允許使用用戶名或電子郵件地址登錄
Duplicate:http://stackoverflow.com/questions/704168/how-to-use-email-instead-of-username-for-user-authentication – 2009-04-22 17:45:35