Django网络聊天室

2024-6-19 337 6/19

Django网络聊天室 Django网络聊天室

项目介绍

本项目是通过django实现的一个实时聊天室,可通过用户登录进入聊天室与不同的用户在聊天室中进行实时聊天,主要由user用户信息部分和chat消息聊天部分组成

实时通信部分实现,是通过定时进行POST请求获取消息列表的方式加载消息列表

运行环境

python3.9.0

PyCharm 2023.1

sqlite3

核心python库

  • django
  • django-bootstrap3

开始

该项目有2个APP

  1. Chat 用于管理聊天记录
  2. 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

主要创建了用户的个人信息表

  1. email 邮箱
  2. QQ
  3. status 登录状态
  4. 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 -

dajavv

6月21日17:43

最后修改:2024年6月21日
1

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论