Auth模块、插拔式设计、BBS表设计
Auth模块
Auth模块是什么
Auth模块是Django自带的用户认证模块:因为我们会实现一些用户的登录、认证、注销等一些功能都需要先去验证,实现起来比较的麻烦.所以Django它默认的使用auth_user表来存储用户的数据.
Auth模块常用方法
form django.contrib import auth # 导入auth模块
1.authenticate()认证
user = authenticate(usernmae='username',password='password')
# 它提供了用户的认证功能,会帮助我们去验证用户名和密码.需要传入username,password两个关键字参数,
如果成功它会返回一个User对象,它会在User对象上设置一个属性来标识后端已经认证了该用户.
2.login(HttpRequest, user)登录功能
from django.contrib.auth import authenticate, login
user = authenticate(username='username',password='password')
if user:
login(request,user)
#该函数会接受一个HttpRequest对象,以及一个经过认证的User对象.
#它是实现一个用户的登录功能,本质上会在后端为该用户生成相关的session数据.
3.logout(request)注销功能
from django.contrib.auth import logout
def logout(request):
logout(request)
# 该模块接收一个HttpRequest对象,无返回值.
# 当调用该函数的时候,当前请求的session信息会全部清除,没有登录使用也不会报错.
4.is_authenticated()判断认证是否通过
def my_view(request):
if request.user.is_authenticated # 它是用来判断用户是否通过了认证.
#request.user.is_authenticated(), 后面加括号能拿到True和False.
5.login_requierd()装饰器工具
form django.contrib.auth.decorators import login_required
@login_required
def my_view(request): # auth给我们提供的一个装饰器工具,用来给视图添加登录校验
# 若你没有登录,它会跳转到django默认的登录URL'/accounts/login/'并传递当前访问url的绝对路径(登录成功之后,会重定向到该路径)
# 你也可以进行自定义登录的URL,需要在配置文件中配置
示例:
settings.py下:
LOGIN_URL = '/login/' # 这里配置你项目登录页面的路由.
6.create_user()创建用户
from django.contrib.auth.models import User
user = User.objects.create_user(usernmae='用户名',password='密码',email='邮箱')
# auth提供的创建新用户的方法.需要提供上面的必须的参数.
7.create_superuser()创建超级用户
from django.contrib.auth.models import User
user = User.objects.create_superuser (username='用户名',password='密码',email='邮箱')
# auth提供一个创建超级用户的方法,需要提供上所需的参数.
8.check_password(password)
ok = user.check_password('密码')
# auth提供的一个检查密码是否正确的方法,需要提供当前用户的密码.
# 密码正确返回True,否则返回False.
set_password(password)
user.set_password(password='')
user.save()
# auth提供的一个修改密码的方法,接收要设置的新密码作为参数.
# 注意: 设置完毕之后一定要调用用户对象的save方法.
User对象的属性
- username, password
- is_staff: 用户是否拥有网站的管理权限
- is_active:是否允许用户登录,设置为False,可以在不删除用户的前提下禁止用户登录
扩展默认的auth_user表
- 内置的认证系统很好用,但是规定的字段是固定的,我想要去加字段.
- 我们可以通过继承内置的AbstractUser, 来定义一个自己的Model类.
- 这样我们不仅能够灵活的添加字段,又能使用Django的认证功能了.
示例:
from dajngo.conrtib.auth.models import AbstractUser
class UserInfo(AbstractUser):
phone = .....
age = ....
# 这样你就可以去灵活的去添加字段了
注意:
1.# 通过上面的方式扩展了auth_user表之后,一定要在settings.py中告诉Django,我们使用了新表来做用户的认证,不然他不知道啊.
AUTH_USER_MODEL = "app01.UserInfo" # 这是固定语法.
2.一旦我们指定了新的认证系统所使用的表,我们就需要在数据库中重新创建该表,而不能使用原来默认的auth_user表了.
根据Auth实现登录等功能
# 注册功能
def register(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password') # 创建一个普通的用户
User.objects.create_user(username=username,password=password,email='123@qq.com')
return render(request, 'register.html')
# 登录功能
def loginn(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user_obj = auth.authenticate(username=username,password=password) # 认证用户.
if user_obj:
print(user_obj)
print(user_obj.password)
auth.login(request,user_obj) # 记录用户的登录状态
old_path = request.GET.get('next')
if old_path:
return redirect(old_path)
else:
return redirect('/home/')
return render(request,'loginn.html')
# 家目录
@login_required
def home(request):
return HttpResponse('我是家目录')
# 判定用户是否通登录
def index(request):
print(request.user) # 使用这个语句就能拿到登录用户的用户对象
print(request.user.is_authenticated) # 看用户是否通过认证,可以反回True和False
return HttpResponse('index')
# 修改用户密码
@login_required
def set_password(request):
if request.method == 'POST':
password = request.POST.get('password')
re_password = request.POST.get('re_password')
ok = request.user.check_password(password)
if ok:
request.user.set_password(re_password)
request.user.save()
return redirect('/loginn/')
return render(request, 'set_password.html', locals())
# 注销功能
@login_required
def logout1(request):
logout(request)
参考中间件,实现功能的插拔式设计
# 实现一个在QQ,微信,email等来进行发消息.
1.新建一个notify文件夹,实现一个功能对应一个py文件.如qq一个py文件,微信一个py文件.这个文件夹相当于一个包,里面有不同功能的模块.
class Msg(object): # 不同的py文件建立多个.
def __init__(self):
pass
def send(self,content): # 鸭子类型,都有发送的功能.
print(f'短信通知{content}')
2.创建一个settings文件夹.
NOTIFY_LIST = [
'notify.email.Msg', # 写入对应的不同功能的路径
...
]
3.在notify文件夹下init下写入.
import settings
import importlib
def send_all(content):
for module_path in settings.NOTIFY_LIST: # 拿到notify.email.Msg,
module, class_name = module_path.rsplit('.',maxsplit=1) # 从右按点切割一次.
# 拿到module = notify.email , class_name = Msg
mod = importlib.import_module(module) # 等价于 from notify import msg
cls = getattr(mod, class_name) # mod相当于一个个的文件夹的名字. class_name是类的名字.在这里面是字符串,意思就去msg文件夹下去寻找一个叫Msg的成员,然后复制给cls,然后通过cls实现对msg文件下类的调用.
obj = cls()
obj.send(content)
4.在run.py文件下.调用.
import notify # 导入notify,调用notify.send_all.就能实现以个一起的来发消息.
notify.send_all('你们好啊') # 这是他实现的一个过程
# 这样做的好处
# 1.如果添加一个功能,直接新建一py问价,然后在settings配置一下就可以调用了.
# 2.若果想不用一个人功能直接在settings里注释掉就可以可.
# 3.且各个功能模块之间不受影响.每一个都是单独的.
BBS表设计
注意事项
1.在评论表里针对对用户id来说, user_id字段可以有多个用户,但是一个用户只有一个id.所以是一对多.
2.在评论表里针对文章id来说,article_id字段可以有多篇文章,但是一篇文章只有一个id,所以是一对多
3.在点赞表里针对用户id来说,user_id字段可以有多个用户,但是一个用户只能对应一个.
4.在点赞表里针对文章id来说,article_id字段可以有多篇文章,但是一篇文章只对应一个id.