这已经是《Python Web 聊天室开发》的第三篇文章了。在前两篇文章中:
在第一篇文章中,我们借助 Django 3 + Channels + Redis 实现了一个WebSocket 连接的 Web 在线聊天室。
在第二篇文章中,我们利用数据库实现了用户聊天记录的保存和漫游。
今天,我们来实现聊天室的用户认证功能,只有登录认证后的用户才能进入聊天室。
用户模型我们使用 Django 提供了AbstractUser
,这保留了 Django 自带了用户模型的所有功能,并且后期还能自定义扩展:
from django.contrib.auth.models import AbstractUser
# 用户模型
class User(AbstractUser):
pass
然后修改聊天记录模型Message
中的字段,将username
字段修改为外键关联到User
模型上:
class Message(models.Model):
username = models.ForeignKey(User,on_delete=models.CASCADE)
room = models.CharField(max_length=255,verbose_name="聊天室")
content = models.TextField(verbose_name="内容")
create_time = models.DateTimeField(auto_now_add=True,verbose_name="写入时间")
class Meta:
ordering = ['-create_time']
最后,在settings.py文件中指定User
模型为系统的认证模型:
AUTH_USER_MODEL = 'chat.User'
并制定登录的 URL:
LOGIN_URL = 'index'
最后执行数据库表迁移的生成命令:
python manage.py makemigrations chat
python manage.py migrate
在之前的代码中,我们直接通过index
视图函数返回首页页面,现在我们需要将其修改一下,实现用户的登录认证(HTML页面也需要修改,后面将会提到)。
首先有一些 django 模块需要引入:
from django.contrib.auth import authenticate,login,logout # 认证相关方法
from django.contrib.auth.decorators import login_required # 登录需求装饰器
如果是 GET 请求,就直接返回 HTML 模板:
# 登录视图
def index(request):
if request.method == 'GET':
return render(request,'index.html',locals())
如果是 POST 请求,则获取表单里面的房间号、用户名、密码,并进行验证:
# 登录视图
def index(request):
if request.method == 'GET':
return render(request,'index.html',locals())
elif request.method == 'POST':
try:
room_name = request.POST.get('room_name','')
username = request.POST.get('username','')
pwd = request.POST.get('password','')
if username != '' and pwd != '' and room_name != '':
user = authenticate(username=username,password=pwd)
if user is not None:
if user.is_active:
login(request,user)
return redirect('room',room_name)
else:
errormsg = '用户被禁用!'
return render(request, 'index.html', locals())
else:
errormsg = '用户名或密码错误!'
return render(request, 'index.html', locals())
else:
errormsg = '房间号、用户名或密码未输入!'
return render(request, 'index.html', locals())
except Exception as e:
errormsg = "异常错误"
return render(request, 'index.html', locals())
然后,我们对聊天室视图函数room
加上登录装饰器login_required
,让这个页面只有在登录后才能访问:
# 聊天室
@login_required()
def room(request,room_name):
room_name = room_name
我们的登录页面也就是之前的首页。
之前的首页表单中有「房间号」和「用户名」两个输入框,现在我们新增一个密码输入框:
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">密码</label>
<div class="layui-input-block">
<input type="password" name="password" id="password-input" placeholder="密码" autocomplete="off" class="layui-input">
</div>
</div>
</div>
修改表单的提交地址和提交方法:
<form class="layui-form" action="{% url 'index' %}" method="post">
然后因为我们的用户模型变了,所以还需要修改一下聊天室room.html
里面聊天记录的遍历方式:
<!-- 聊天记录 -->
<div id="chat-record">
{% for m in msgs %}
{% if m.username.username == request.user.username %}
<div class="right_msg">{{m.username}}<div class="right-record"><span>{{m.content}}</span></div></div><br>
{% else %}
<div class="left_msg">{{m.username}}<div class="left-record"><span>{{m.content}}</span></div></div><br>
{% endif %}
{% endfor %}
</div>
这样就大功告成了。
完成上述步骤之后,我们这个在线聊天室就只能登录认证后的用户可以进入聊天室了。
登录页:
登录错误信息提示:
完整的动图演示:
如果未登录的用户直接访问聊天房间的URL,则会跳转到登录首页:
这样,我们就完成了在线聊天室的用户认证功能扩展。
总结起来就是 3 步:
是不是很简单?
🧐分享、点赞、在看,给个鼓励吧!👇