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": "用户名或密码错误"})
网友评论