Auth模块插拔式设计BBS表设计

Posted kangwy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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表

  1. 内置的认证系统很好用,但是规定的字段是固定的,我想要去加字段.
  2. 我们可以通过继承内置的AbstractUser, 来定义一个自己的Model类.
  3. 这样我们不仅能够灵活的添加字段,又能使用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.

以上是关于Auth模块插拔式设计BBS表设计的主要内容,如果未能解决你的问题,请参考以下文章

auth模块 + 插拔式思想

☆Django☆---中间件 csrf跨站请求伪造 auth模块 settings功能插拔式源码

Python Django 生命周期 中间键 csrf跨站请求伪造 auth认证模块 settings功能插拔式源码

21 参考中间件,实现可插拔式设计

带你手写基于 Spring 的可插拔式 RPC 框架整体结构

# "可插拔式"组件设计,领略组件开发的奥秘