您好,登錄后才能下訂單哦!
本篇文章為大家展示了Django中怎么實現一個用戶認證系統,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
你可以通過is_authenticated()來區分,例如:
if request.user.is_authenticated(): # Do something for authenticated users. else: # Do something for anonymous users.
登陸login
login()
登陸函數,需要一個HttpRequest對象和一個User對象作參數。login()使用django的session框架,將User的id存儲在session中。
同時使用authenticate()和login():
from django.contrib.auth import authenticate, login def my_view(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None: if user.is_active: login(request, user) # Redirect to a success page. else: # Return a 'disabled account' error message else: # Return an 'invalid login' error message.
如果不知道密碼,login方法:
user=MyUser.objects.get(...) user.backend = 'django.contrib.auth.backends.ModelBackend' login(request,user)
退出登錄logout
logout()
使用HttpRequest對象為參數,無返回值。例如:
from django.contrib.auth import logout def logout_view(request): logout(request) # Redirect to a success page.
限制訪問
The raw way
使用 request.user.is_authenticated()
再定向:
from django.shortcuts import redirect def my_view(request): if not request.user.is_authenticated(): return redirect('/login/?next=%s' % request.path) # ...
或者:
from django.shortcuts import render def my_view(request): if not request.user.is_authenticated(): return render(request, 'myapp/login_error.html') # ...
使用裝飾器login_required
login_required([redirect_field_name=REDIRECT_FIELD_NAME, login_url=None]
from django.contrib.auth.decorators import login_required @login_required def my_view(request): ...
如果用戶未登錄,則重定向到 settings.LOGIN_URL,并將現在的url相對路徑構成一個next做key的查詢字符對附加到 settings.LOGIN_URL后面去:
/accounts/login/?next=/polls/3/.
query字符對的key默認為next,也可以自己命名:
from django.contrib.auth.decorators import login_required @login_required(redirect_field_name='my_redirect_field') def my_view(request): ...
也可以自己定義login_url:
from django.contrib.auth.decorators import login_required @login_required(login_url='/accounts/login/') def my_view(request): ...
urls.py中需定義:
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
測試登錄用戶
例如,要檢測用戶的email:
def my_view(request): if not '@example.com' in request.user.email: return HttpResponse("You can't vote in this poll.") # ...
可以用裝飾器:
from django.contrib.auth.decorators import user_passes_test def email_check(user): return '@example.com' in user.email @user_passes_test(email_check) def my_view(request): ...
也可以改變login_url:
@user_passes_test(email_check, login_url='/login/') def my_view(request): ...
認證Views
當然,我們可以自己定義一些登陸,登出,密碼管理的view 函數,而且也更加方便。
不過也可以學習下Django內置的views。
Django沒有為認證views提供缺省模板,however the template context is documented for each view below.
所有內置views都返回一個TemplateResponse實例,可以讓你很方便的定制response數據。
https://github.com/django/django/blob/master/django/contrib/auth/views.py
多數的內置認證views都提供一個URL名稱以便使用。
login(request[, template_name, redirect_field_name, authentication_form,current_app,extra_context])
源碼:
def login(request, template_name='registration/login.html', redirect_field_name=REDIRECT_FIELD_NAME, authentication_form=AuthenticationForm, current_app=None, extra_context=None): """ Displays the login form and handles the login action. """ redirect_to = request.POST.get(redirect_field_name, request.GET.get(redirect_field_name, '')) if request.method == "POST": form = authentication_form(request, data=request.POST) if form.is_valid(): # Ensure the user-originating redirection url is safe. if not is_safe_url(url=redirect_to, host=request.get_host()): redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL) # Okay, security check complete. Log the user in. auth_login(request, form.get_user()) return HttpResponseRedirect(redirect_to) else: form = authentication_form(request) current_site = get_current_site(request) context = { 'form': form, redirect_field_name: redirect_to, 'site': current_site, 'site_name': current_site.name, } if extra_context is not None: context.update(extra_context) return TemplateResponse(request, template_name, context, current_app=current_app)
URL name: login
參數:
template_name: 默認的登陸模板.默認為registration/login.html.
redirect_field_name: 重定向的name,默認為next.
authentication_form: 默認Form. Defaults to AuthenticationForm.
current_app: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
extra_context: 添加到默認context data中的額外數據,為字典。
django.contrib.auth.views.login does:
如果通過GET訪問, 將顯示登錄表單,可以將其內容POST到相同的URL上。
如果通過POST訪問,它首先會嘗試登錄,如果成功,view就重定向到next指定的的鏈接。如果next 未設置,則重定向到settings.LOGIN_REDIRECT_URL(一般缺省值為accounts/profile/)。如果登錄失敗,則再次顯示登錄表單。
需要用戶自己來提供login的html模板,缺省是registration/login.html 。這個模板將傳遞4個模板上下文變量:
form: 一個表單對象AuthenticationForm.
next: 登錄成功后的重定向鏈接,可以包含一個query string中。
site: 當前網站,根據 SITE_ID 設置。如果你并沒有安裝site框架,這個變量將設定為一個 RequestSite實例,它從當前 HttpRequest中取得站點名和域名。
site_name: 是 site.name的一個別名。如果你沒有安裝site框架,它將會被設為 request.META['SERVER_NAME']的值。
如果你不想調用registration/login.html模板,你可以在URLconf中設定特定的view參數來傳遞template_name參數。
(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}),
你也可以自己指定重定向鏈接字段名,通過redirect_field_name 參數。默認的字段名為next.
下面是registration/login.html 模板的原始狀態,它假定你有一個base.html模板(其中有content block的定義。
{% extends "base.html" %} {% block content %} {% if form.errors %} <p>Your username and password didn't match. Please try again.</p> {% endif %} <form method="post" action="{% url 'django.contrib.auth.views.login' %}"> {% csrf_token %} <table> <tr> <td>{{ form.username.label_tag }}</td> <td>{{ form.username }}</td> </tr> <tr> <td>{{ form.password.label_tag }}</td> <td>{{ form.password }}</td> </tr> </table> <input type="submit" value="login" /> <input type="hidden" name="next" value="{{ next }}" /> </form> {% endblock %}
如果自己定制認證系統,可以通過 authentication_form 參數把自定義的認證表單傳給login view。該表單的__init__ 方法應該有一個request 的參數,并提供一個 get_user 方法來返回認證后的User對象。
logout(request[, next_page, template_name, redirect_field_name, current_app,extra_context])
登出用戶.
URL name: logout
可選參數:
next_page: 注銷后的重定向鏈接.
logout_then_login(request[, login_url, current_app, extra_context])
注銷用戶然后重定向到登錄鏈接.
可選參數:
login_url: 登陸頁面的重定向鏈接,缺省值為 settings.LOGIN_URL。
password_change(request[, template_name, post_change_redirect,password_change_form,current_app, extra_context])
允許用戶修改密碼.
URL name: password_change
可選參數 Optional arguments:
template_name: 模板名,缺省值為registration/password_change_form.html 。
post_change_redirect: 重定向鏈接。
password_change_form: 自定義的密碼修改表單,包括一個user 參數。缺省值為PasswordChangeForm.
password_change_done(request[, template_name,current_app, extra_context])
用戶修改密碼后的頁面.
URL name: password_change_done
可選參數 Optional arguments:
template_name: 模板名稱,缺省為registration/password_change_done.html.
password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect, from_email, current_app, extra_context, html_email_template_name])
向用戶發送郵件,內含一個一次性鏈接,來讓用戶重設密碼。
如果提供的郵箱不存在,則不會發送。
URL name: password_reset
可選參數 Optional arguments:
template_name: 模板名稱,缺省值為registration/password_reset_form.html。
email_template_name: 用來生成帶充值鏈接email的模板名稱,缺省值為registration/password_reset_email.html。
subject_template_name: 用來生成郵件主題的模板名稱,缺省值為 registration/password_reset_subject.txt。
password_reset_form: 重設密碼的表單,缺省值為 PasswordResetForm.
token_generator: 檢查一次性鏈接的類實例,缺省值為default_token_generator, 其類為django.contrib.auth.tokens.PasswordResetTokenGenerator.
post_reset_redirect: 密碼重置后的重定向鏈接.
from_email: 郵件地址,缺省值為DEFAULT_FROM_EMAIL.
current_app: A hint indicating which application contains the current view. See the namespaced URL resolution strategy for more information.
extra_context: A dictionary of context data that will be added to the default context data passed to the template.
html_email_template_name: The full name of a template to use for generating a text/html multipart email with the password reset link. By default, HTML email is not sent.
示例: registration/password_reset_email.html (email內容模板):
Someone asked for password reset for email {{ email }}. Follow the link below: {{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
password_reset_done(request[, template_name])
顯示用戶選擇發送密碼重置郵件后的頁面。如果 password_reset() view中沒有顯式指定post_reset_redirect鏈接時,則直接調用本view。
password_reset_confirm(request[, uidb36, token, template_name, token_generator,set_password_form, post_reset_redirect,current_app, extra_context])
顯示輸入新密碼的表單.
password_reset_complete(request[, template_name, current_app, extra_context])
重置密碼成功后的表單。
Helper functions
redirect_to_login(next[, login_url, redirect_field_name])
重定向到登錄頁面,登錄成功后的在重定向到另一鏈接。.
參數:
next: 登錄成功后的鏈接.
login_url: 登陸頁面鏈接,默認缺省值:settings.LOGIN_URL。
redirect_field_name: 重定向字段名稱,缺省值為next。
內置表單 Built-in forms
class AdminPasswordChangeForm
admin后臺的用戶密碼修改表單
class AuthenticationForm
登錄表單。
方法confirm_login_allowed(user)
例如,允許所有的users登陸,不管is_active屬性:
from django.contrib.auth.forms import AuthenticationForm class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm): def confirm_login_allowed(self, user): pass
或者只允許活躍用戶登陸:
class PickyAuthenticationForm(AuthenticationForm): def confirm_login_allowed(self, user): if not user.is_active: raise forms.ValidationError( _("This account is inactive."), code='inactive', ) if user.username.startswith('b'): raise forms.ValidationError( _("Sorry, accounts starting with 'b' aren't welcome here."), code='no_b_users', )
class PasswordChangeForm
修改密碼表單.
class PasswordResetForm
密碼重置表單.
class SetPasswordForm
密碼設置表單.
class UserChangeForm
admin后臺的用戶信息和權限修改表單.
class UserCreationForm
用戶創建表單.
模板中的認證信息 Authentication data in templates
當前登錄用戶及其權限可以在模板變量中取得,通過使用RequestContext.
Users
在渲染模板 RequestContext時,當前的登錄用戶無論是User實例還是AnonymousUser 實例均保存在模板變量 {{ user }}:
{% if user.is_authenticated %} <p>Welcome, {{ user.username }}. Thanks for logging in.</p> {% else %} <p>Welcome, new user. Please log in.</p> {% endif %}
如果未使用 RequestContext,則此變量不存在。
使用RequestContext:
from django.shortcuts import render_to_response from django.template import RequestContext def some_view(request): # ... return render_to_response('my_template.html', my_data_dictionary, context_instance=RequestContext(request))
上述內容就是Django中怎么實現一個用戶認證系統,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。