项目介绍
本项目是通过django实现的一个实时聊天室,可通过用户登录进入聊天室与不同的用户在聊天室中进行实时聊天,主要由user用户信息部分和chat消息聊天部分组成
实时通信部分实现,是通过定时进行POST请求获取消息列表的方式加载消息列表
运行环境
python3.9.0
PyCharm 2023.1
sqlite3
核心python库
- django
-
django-bootstrap3
开始
该项目有2个APP
- Chat 用于管理聊天记录
- User 用于管理用户信息
项目基础设置
#在INSTALLED_APPS中添加
'bootstrap3', # django-bootstrap3用于快速布局html
'User.apps.UserConfig', # APP
'Chat.apps.ChatConfig', # APP
#更改语言
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
#开发端口
ALLOWED_HOSTS = ['*']
User部分
模型models
主要创建了用户的个人信息表
-
email 邮箱
-
status 登录状态
-
sex 性别
from django.db import models
from django.contrib.auth.models import AbstractUser, UserManager
from django.utils.translation import gettext_lazy as _
import hashlib
import random
# from django.utils.timezone import now
# Create your models here.
class ShadowUserManager(UserManager): # 创建用户
def create_superuser(self, username, email, password, **extra_fields):#创建超级用户
extra_fields.setdefault('is_staff', True) #
extra_fields.setdefault('is_superuser', True) # 是否为超级用户
extra_fields.setdefault('QQ', '') # QQ
extra_fields.setdefault('sex', 'M') # 性别
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(username, email, password, **extra_fields)
def _create_user(self, username, email, password, **extra_fields):#创建用户
if not username:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
username = self.model.normalize_username(username)
user = self.model(username=username, email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username, email=None, password=None, **extra_fields):#创建用户
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
extra_fields.setdefault('QQ', '')
extra_fields.setdefault('is_active', False)
extra_fields.setdefault('sex', 'M')
return self._create_user(username, email, password, **extra_fields)
class User(AbstractUser): # 用户聊天信息表,记录在聊天时的个人信息以及状态
GENDER_CHOICES = (
('F', '女'),
('M', '男'),
('U', '未知')
)
email = models.EmailField(_('email address'), blank=True) # 邮箱
QQ = models.CharField(default='', max_length=60) # QQ
status = models.BooleanField(default=False, verbose_name="Status") # 状态,在线or离线
sex = models.CharField(max_length=2, choices=GENDER_CHOICES, default='M') # 性别
objects = ShadowUserManager()
def get_avatar(self):
return hashlib.md5(self.email.encode()).hexdigest()
视图部分
在视图中,在这里对用户登录进行了加载,首先第一次进入页面时,会进行GET请求,此时,将要渲染的模版和创建的表单对象进行返回。
当用户输入登录信息,点击登录按钮后,会进行POST请求,此时,需要对表单对象的信息进行验证,不正确就进行重定向会到登录login页面。
from django.shortcuts import render, redirect, render, reverse
from django.contrib.auth.views import LoginView, LogoutView
from django.views.generic.base import TemplateView
from User.form import CreationForm
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
# from django.contrib import messages
from django.core.mail import send_mail
from django.utils.timezone import now
import os
# Create your views here.
# 用户登录
class user_login_view(LoginView):
template_name = 'User/login.html'
redirect_authenticated_user = True
class user_logout_view(LogoutView):
template_name = 'User/login.html'
next_page = '/login'
@csrf_exempt # 免除csrf令牌
def user_adduser_view(request):
template_name = 'User/sign-up.html'
context = {
"add_form": CreationForm(), # 创建用户表单验证form.py对象
}
if request.method == "GET": # 判断请求类型
return render(template_name, context)#渲染登录页面html和空表单,登录页面表单直接读取创建的空表单对象
if request.method == "POST": # 判断请求类型
add_form = CreationForm(request.POST) # 获取已填写的CreationForm表单对象信息
if add_form.is_valid():#登录验证
if add_form.clean_password2():
add_form.save(commit=True)
return redirect('/login')#密码验证失败,重定向到登录页面
表单对象
用于验证登录时的表单信息
#User/form.py
from User.models import User
from django.contrib.auth.forms import UserCreationForm
from django.forms import ModelForm
#用户表单验证
class CreationForm(UserCreationForm):
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class Meta:
model = User
fields = ['username',
'first_name',
'last_name',
'email',
'QQ',
'sex',
]
labels = { 'sex': '性别', }
help_texts = {'email': '用于获取你的Gravatar.com网站的头像.如果您没有使用,请立即注册', }
路由
#User/urls.py
from django.urls import path
from . import views
app_name = 'User'
urlpatterns = [
path('login/', views.user_login_view.as_view()), # 登录
path('logout/', views.user_logout_view.as_view()), # 注销用户API
path('', views.user_login_view.as_view()),
path('sign-up/', views.user_adduser_view), # 发送消息API
]
Chat部分
模型models
#Chat/models.py
from django.db import models
from User.models import User
import hashlib
# Create your models here.
class Chat(models.Model):#聊天记录表
sender = models.ForeignKey(User,verbose_name='has_chats', on_delete=models.CASCADE)#信息发送方
content = models.TextField(max_length=200)#内容
time = models.DateTimeField(auto_now_add=True, null=True)#发送时间
def get_avatar(self):
return hashlib.md5(self.sender.email.encode()).hexdigest()
def __unicode__(self):
return self.content
视图
#Chat/views.py
from django.shortcuts import HttpResponse, render, redirect, Http404
from django.views.generic import ListView
from Chat.models import Chat # 数据库
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.mixins import LoginRequiredMixin#需要登录
# Create your views here.
class ChatView(LoginRequiredMixin, ListView):
model = Chat # 数据库
template_name = 'Chat/chat.html' # 模版
@csrf_exempt
# 免除csrf令牌
def post(request): # 消息发送和消息列表加载
if request.method == 'POST' and request.user.is_authenticated: # 判断消息类型
post_type = request.POST.get('post_type') # 判断send_chat发送消息或get_chat获取消息列表
if post_type == 'send_chat': # 发送消息
new_chat = Chat.objects.create( # 向数据库添加消息数据
content=request.POST.get('content'), # 从请求消息获取post请求中的消息内容
sender=request.user, # 从请求消息中获取请求的用户名
)
new_chat.save() # 更新数据库
return HttpResponse()
elif post_type == 'get_chat': # 获取消息列表
last_chat_id = int(request.POST.get('last_chat_id')) # 聊天id
chats = Chat.objects.filter(id__gt=last_chat_id) # 通过id对数据库消息进行查找
return render(request, 'Chat/chat_update.html', {'chats': chats}) # 模版渲染,返回数据列表
else:
raise Http404
路由
#Chat/urls.py
from django.urls import path
from . import views
app_name = 'Chat'
urlpatterns = [
path('', views.ChatView.as_view()),
path('post/', views.post),#信息发送API
]
213
- THE END -
最后修改:2024年6月21日
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://cpxigxs.cn/2024/06/19/django-bootstrap3%e7%bd%91%e7%bb%9c%e8%81%8a%e5%a4%a9%e5%ae%a4/
共有 0 条评论