登录
在使用authenticate进行验证后,如果验证通过了。那么会返回一个user对象,拿到user对象后,可以使用django.contrib.auth.login进行登录。
这里使用的models是继承自AbstractBaseUser的模型
# models.pyfrom django.contrib.auth.models import AbstractBaseUser, BaseUserManagerfrom django.contrib.auth.models import PermissionsMixinclass UserManager(BaseUserManager):def _create_user(self, phone, username, password, **kwargs):# 这是一个受保护函数,只能被类自己中调用# 作为create_user和create_superuser的被调用函数if not phone:raise ValueError("必须传递手机号码")if not password:raise ValueError("必须传递密码")user = self.model(phone=phone, username=username, **kwargs) # self.model表示当前模型user.set_password(password) # password只能这样设置user.save()return userdef create_user(self, phone, username, password, **kwargs):kwargs["is_superuser"] = False # 添加is_superuser键值对return self._create_user(phone=phone, username=username, password=password, **kwargs)def create_superuser(self, phone, username, password, **kwargs):kwargs["is_superuser"] = Truereturn self._create_user(phone=phone, username=username, password=password, **kwargs)class InheritTwo(AbstractBaseUser, PermissionsMixin):phone = models.CharField(max_length=11, unique=True)username = models.CharField(max_length=20)password = models.CharField(max_length=20)address = models.CharField(max_length=100)is_active = models.BooleanField(default=True)USERNAME_FIELD = 'phone'REQUIRED_FIELDS = []objects = UserManager()def get_full_name(self):return self.usernamedef get_short_name(self):return self.username
配置settings.py中的AUTH_USER_MODEL='appname.InheritTwo',且为第一次数据库迁移
html编写
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Login</title></head><body><form action="" method="post"><input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}"><table><tbody><tr><td>登陆手机号:</td><td><input type="text" name="phone"></td></tr><tr><td>密码:</td><td><input type="password" name="password"></td></tr><tr><td><label for=""><input type="checkbox" name="remember" value="1"> 记住我</label></td><td></td></tr><tr><td></td><td><input type="submit" value="登陆"></td></tr></tbody></table></form></body></html>
登陆:
from django.shortcuts import render, redirect, reversefrom .forms import LoginFormfrom django.contrib.auth import login, logoutdef my_login(request):if request.method == "GET":return render(request, 'login.html')if request.method == "POST":form = LoginForm(request.POST)if form.is_valid():phone = form.cleaned_data.get("phone")password = form.cleaned_data.get("password")remember = form.cleaned_data.get("remember")user = authenticate(request, username=phone, password=password)# authenticate验证if user and user.is_active: # 如果存在且不为黑名单# 在session表中登记信息login(request, user)if remember: # 是否有点"记住我"# 设置为None,则表示使用全局的默认时间(2周)request.session.set_expiry(None)else:# 浏览器结束即结束request.session.set_expiry(0)return HttpResponse("登陆成功")else:return HttpResponse("手机或密码错误")else:return redirect(reverse('login'))
注销
注销,或者说退出登录。通过django.contrib.auth.logout来实现。他会清理掉这个用户的session数据(表也会清除,类似request.session.flush())。
from django.contrib.auth import logoutdef my_logout(request):logout(request)return HttpResponse("登出成功")
登录限制:使用装饰器
需要某个视图函数是需要经过登录后才能访问的。
通过django.contrib.auth.decorators.login_required装饰器来实现。
from django.contrib.auth.decorators import login_required@login_required(login_url='/login/') # 如果验证失败,则跳转login_url指定的页面# 会传递 next= urls.py中视图函数对应的urls路径# 比如当前函数的urls路径为 two/profile/ 则传递 next=/two/prifle/ <-!!!没有多一个 /def profile(request):return HttpResponse("登陆成功才能看见")
在/login/的视图函数中,判断是否有这个next查询字符串,决定是否再跳转到profile视图函数
def my_login(request):# ...if user and user.is_active: # 如果存在且不为黑名单# request.session['user_id'] = user.idlogin(request, user)if remember:# 设置为None,则表示使用全局的默认时间(2周)request.session.set_expiry(None)else:request.session.set_expiry(0)next_url = request.GET.get('next') # 装饰器login_request修饰的函数跳转后会传递next查询字符串if next_url:return redirect(next_url) # 跳转回profile视图函数else:return HttpResponse("登陆成功")else:return HttpResponse("手机或密码错误")# ...
