17.用戶登錄2

views.py還需要修改,authenticate的參數需要寫名字,且響應函數不能和系統默認名相同。

from django.shortcuts import render
from django.contrib.auth import authenticate, login
# Create your views here.
def user_login(request):

    if request.method == "POST":
        user_name = request.POST.get("username","")
        pass_word = request.POST.get("password","")
        user = authenticate(username=user_name, password=pass_word)
        if user is not None:
            login(request,user)
            return render(request,"index.html")
        else:
            return render(request,"login.html",{})
    elif request.method == "GET":
        return render(request, "login.html", {})

urls.py里的響應函數名也要改。然后就可以登陸了。然后如果想要郵箱和用戶名都能登錄,需要自定義 authenticate的功能。先在settings.py里AUTHENTICATION_BACKENDS = (
'apps.users.views.CustomerBackend',
)
在views里:

from django.shortcuts import render
from django.contrib.auth import authenticate, login
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q

from users.models import UserProfile
class CustomerBackend(ModelBackend):
    def authenticate(self, username=None, password=None, **kwargs):
        try:
            user = UserProfile.objects.get(Q(username=username)|Q(email = username))
            if user.check_password(password):   
                return user
        except Exception as e:
            return None

# Create your views here.

def user_login(request):

    if request.method == "POST":
        user_name = request.POST.get("username","")
        pass_word = request.POST.get("password","")
        user = authenticate(username=user_name, password=pass_word)
        if user is not None:
            login(request,user)
            return render(request,"index.html")
        else:
            return render(request,"login.html",{})
    elif request.method == "GET":
        return render(request, "login.html", {})

創建一個類繼承ModelBackend類,在里面可以自定義authenticate方法,它就是下邊響應函數中的authenticate,現在可以自定義這個函數了。userprofile繼承了AbstractUser類,可以直接調用里面的方法user.check_password。因為不能直接對比輸入密碼和數據庫里的密碼,一個是明文一個不是,要用這個方法檢查。雖然只是創建了類CustomerBackend,但打開網頁可以發現程序運行進入了這個類的邏輯里。Q這個方法支持并集和且的關系。get(Q(username=username)|Q(email = username))意思是輸入的用戶名等于數據庫里的username可以,等于email也可以。
再增加個功能,在用戶輸入錯誤的賬戶密碼時提示錯誤.把響應函數里的else部分寫成

return render(request,"login.html",{"msg":"用戶名或密碼錯誤"})

然后把這個msg寫在login.html里

 </div>
                    <div class="error btns login-form-tips" id="jsLoginTips">{{ msg }}</div>
                     <div class="auto-box marb38">

還有一種更好的登錄實現方式,基于類的方法。views.py里

from django.shortcuts import render
from django.contrib.auth import authenticate, login
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.views.generic.base import View

from users.models import UserProfile
class CustomerBackend(ModelBackend):
    def authenticate(self, username=None, password=None, **kwargs):
        try:
            user = UserProfile.objects.get(Q(username=username)|Q(email = username))
            if user.check_password(password):
                return user
        except Exception as e:
            return None

class LoginView(View):     #這樣就不用做POST和GET的判斷了,django根據情況自己調用
    def get(self,request):
        return render(request, "login.html", {})
    def post(self,request):
        user_name = request.POST.get("username", "")
        pass_word = request.POST.get("password", "")
        user = authenticate(username=user_name, password=pass_word)
        if user is not None:
            login(request, user)
            return render(request, "index.html")
        else:
            return render(request, "login.html", {"msg": "用戶名或密碼錯誤"})

urls里

from django.conf.urls import url
from django.contrib import admin
from django.views.generic import TemplateView
from users.views import LoginView
import xadmin

from apps.users.views import login

urlpatterns = [
    url(r'^xadmin/', xadmin.site.urls),
    url('^$', TemplateView.as_view(template_name="index.html"),name="index"),
    url('^login/$', LoginView.as_view(),name="login")  #as_view()方法判斷是post還是get然后返回響應函數名
]

as_view()方法判斷是post還是get然后返回響應函數名。
form可以對前端表單傳遞到后端的數據是否滿足要求,滿足要求再進入邏輯。現在users里創建forms.py:

from django import forms
class LoginForm(forms.Form):
    username = forms.CharField(required=True)
    password = forms.CharField(required=True,min_length=5)

需要和前端html文件里表單的變量名相同,否則不能檢驗。
views.py里LoginView類改為

from .forms import  LoginForm
class LoginView(View):     #這樣就不用做POST和GET的判斷了,django根據情況自己調用
    def get(self,request):
        return render(request, "login.html", {})
    def post(self,request):
        login_form = LoginForm(request.POST)  #前端的html文件中變量名必須和forms里定義的兩個名字相同才能自動檢查
        if login_form.is_valid():   #is_valid檢查login_form的error是否為空,為空則滿足條件
            user_name = request.POST.get("username", "")
            pass_word = request.POST.get("password", "")
            user = authenticate(username=user_name, password=pass_word)
            if user is not None:
                login(request, user)
                return render(request, "index.html")
        else:
            return render(request, "login.html", {"msg": "用戶名或密碼錯誤"})

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。