虽说有 django-allauth 这个很好用的轮子在,但是自己造个轮子更能加深对DJango的理解,也更灵活下面记录一下 Django用户登陆,注册等自定义实现的知识。
用户登陆
- 函数实现方式
from django.contrib.auth import authenticate, login
def user_login(request):
if request.method == "POST":
user_name = request.POST.get("username", "") # 获取form传递过来的POST中的参数 默认值为空
pass_word = request.POST.get("password", "")
user = authenticate(username=user_name, password=pass_word) #验证用户(如果验证通过会返回UserProfile对象,否则返回None)
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')
- 类的实现方式
from django.contrib.auth import authenticate, login
from django.views.generic.base import View
class LogView(View):
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": "用户名或密码错误"})
类和函数的区别
- 类可以继承
- 类下面可以写很多函数方法
类似上面的例子其实功能性代码是一样的 只是类比函数少了一些if判断
类通过复写 get和post方法 自动调用相关代码,相比 函数架构更好。
自定义 authenticate
DJango默认的 authenticate 不能做到类似 邮箱账号或手机号登陆,但是我们可以复写(重载)authenticate
- Q 是用来实现 或| 的
# 任意views中插入如下代码
from django.contrib.auth.backends import ModelBackend
from .models import UserProfile
from django.db.models import Q
class CustomBackend(ModelBackend):
def authenticate(self, username=None, password=None, **kwargs):
try:
user = UserProfile.objects.get(Q(username=username)|Q(email=username)) # 同理还可以加一个 |Q(iphone=username)
if user.check_password(password):
return user
except Exception as e:
return None
# setting.py 项目setting.py中插入如下 users就是上述代码插入的app.views
# Application definition
AUTHENTICATION_BACKENDS = (
'users.views.CustomBackend',
)
使用form验证
form 表单是 Web开发很重要的一个组件
在用户登陆这个动作中 使用 form 可以提前对数据进行验证,比如非空,字符串长度等等,直接在 前端就对数据进行了验证,减少了对数据库的压力。
- 在 app 中 新建一个 forms.py
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(required=True) #验证非空
password = forms.CharField(required=True, min_length=5) #验证非空,字符串不小于5
# views.py
from .forms import LoginForm #导入新建的form类
class LoginView(View):
def get(self, request):
return render(request, "login.html", {})
def post(self, request):
login_form = LoginForm(request.POST) #实例化form对象传入POST数据 会自动去验证POST中的同名参数(username password)
if login_form.is_valid(): #判断表单是否验证成功
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":"用户名或密码错误!"})
else:
return render(request, "login.html", {"login_form":login_form})
将 form 的错误信息返回到前端
form 验证失败后会返回一个 errordict
image.png
要将这个错误信息显示到前端只需要将 返回的 login_form 对象传递到 temple 中
image.png
再像上面这个 输出 error
image.png
网友评论