ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

djangochannelsrestframework 入门教程:从零搭建实时聊天室的完整 7 步指南

djangochannelsrestframework 入门教程:从零搭建实时聊天室的完整 7 步指南 djangochannelsrestframework 入门教程从零搭建实时聊天室的完整 7 步指南【免费下载链接】djangochannelsrestframeworkA Rest-framework for websockets using Django channels-v4项目地址: https://gitcode.com/gh_mirrors/dj/djangochannelsrestframeworkdjangochannelsrestframework简称 DCRF是一个基于 Django Channels v4 构建 WebSocket 实时接口的框架它提供了类似 Django REST FrameworkDRF的编程体验让你能用熟悉的 Serializer、Mixin 和权限体系快速开发实时应用。本文将通过搭建一个实时聊天室带你完整体验从安装、建模到前后端联调的 7 个核心步骤即使是刚接触 WebSocket 的新手也能轻松跟上。为什么选择 djangochannelsrestframework传统的 Django 开发中HTTP 接口用 DRF 就能优雅解决但一旦涉及实时推送聊天、通知、在线状态就必须接触 Channels 中略显繁琐的 Consumer 写法。djangochannelsrestframework 的价值在于复用 DRF 技能Serializer、permission、Mixin 全部沿用你熟悉的 DRF 概念⚡异步原生基于 Channels v4天然支持高并发 WebSocket 连接内置观察者模式model_observer可以让你像订阅信号一样监听模型变化并实时推送开箱即用一行pip install即可获得完整的 REST 风格 WebSocket API第一步安装 djangochannelsrestframework 与准备工作在已经完成 Django 与 Channels 基础教程的前提下只需在同一个 Python 环境中执行pip install djangochannelsrestframework安装后请确认项目的settings.py中已正确配置ASGI_APPLICATION和channels应用。这里有一个官方特别强调的坑在路由中声明 Consumer 时必须使用.as_asgi()类方法例如RoomConsumer.as_asgi()千万不要在代码里实例化RoomConsumer()否则会引发严重问题。第二步创建聊天室的数据模型一个聊天室至少需要三个模型用户、房间和消息。参考官方教程docs/tutorial/part_1.rst在chat/models.py中写入from django.db import models from django.contrib.auth.models import AbstractUser class User(AbstractUser): pass class Room(models.Model): name models.CharField(max_length255, nullFalse, blankFalse, uniqueTrue) host models.ForeignKey(User, on_deletemodels.CASCADE, related_namerooms) current_users models.ManyToManyField(User, related_namecurrent_rooms, blankTrue) class Message(models.Model): room models.ForeignKey(chat.Room, on_deletemodels.CASCADE, related_namemessages) text models.TextField(max_length500) user models.ForeignKey(User, on_deletemodels.CASCADE, related_namemessages) created_at models.DateTimeField(auto_now_addTrue)同时别忘了在settings.py中注册自定义用户模型AUTH_USER_MODEL chat.User然后执行迁移命令同步数据库。第三步编写聊天数据的 DRF 序列化器DCRF 最大的爽点就在这里——你之前写的 DRF Serializer 可以直接复用在chat/serializers.py中定义三个序列化器用于处理用户、消息和房间数据的 JSON 转换from rest_framework import serializers from .models import User, Room, Message class UserSerializer(serializers.ModelSerializer): class Meta: model User exclude [password] class MessageSerializer(serializers.ModelSerializer): created_at_formatted serializers.SerializerMethodField() user UserSerializer() class Meta: model Message exclude [] depth 1 def get_created_at_formatted(self, obj): return obj.created_at.strftime(%d-%m-%Y %H:%M:%S) class RoomSerializer(serializers.ModelSerializer): last_message serializers.SerializerMethodField() messages MessageSerializer(manyTrue, read_onlyTrue) class Meta: model Room fields [pk, name, host, messages, current_users, last_message] depth 1 read_only_fields [messages, last_message]第四步编写核心 Consumer最关键的一步这是整个 djangochannelsrestframework 教程的重头戏。我们创建一个继承ObserverModelInstanceMixin和GenericAsyncAPIConsumer的RoomConsumer核心类定义在源码djangochannelsrestframework/generics.py中它负责处理 WebSocket 连接期间的各类 action。import json from channels.db import database_sync_to_async from djangochannelsrestframework.generics import GenericAsyncAPIConsumer from djangochannelsrestframework.observer import model_observer from djangochannelsrestframework.observer.generics import ObserverModelInstanceMixin, action from .models import Message, Room, User from .serializers import MessageSerializer, RoomSerializer, UserSerializer class RoomConsumer(ObserverModelInstanceMixin, GenericAsyncAPIConsumer): queryset Room.objects.all() serializer_class RoomSerializer lookup_field pk async def disconnect(self, code): if hasattr(self, room_subscribe): await self.remove_user_from_room(self.room_subscribe) await self.notify_users() await super().disconnect(code) action() async def join_room(self, pk, **kwargs): self.room_subscribe pk await self.add_user_to_room(pk) await self.notify_users() action() async def create_message(self, message, **kwargs): room await self.get_room(pkself.room_subscribe) await database_sync_to_async(Message.objects.create)( roomroom, userself.scope[user], textmessage )用 model_observer 实现消息实时推送model_observer是 DCRF 的杀手锏当Message模型有新增时它会自动把变更推送给所有订阅者。配合groups_for_signal和serializer两个装饰方法就能实现按房间分组推送model_observer(Message) async def message_activity(self, message, observerNone, subscribing_request_ids[], **kwargs): for request_id in subscribing_request_ids: message_body dict(request_idrequest_id) message_body.update(message) await self.send_json(message_body) message_activity.groups_for_signal def message_activity(self, instance: Message, **kwargs): yield froom__{instance.room_id} yield fpk__{instance.pk} message_activity.groups_for_consumer def message_activity(self, roomNone, **kwargs): if room is not None: yield froom__{room} message_activity.serializer def message_activity(self, instance: Message, action, **kwargs): return dict(dataMessageSerializer(instance).data, actionaction.value, pkinstance.pk)注意一个小技巧凡是涉及数据库同步操作的代码都要用database_sync_to_async包裹避免阻塞事件循环。源码中的相关辅助方法可参考djangochannelsrestframework/consumers.py和djangochannelsrestframework/observer/generics.py。第五步配置 WebSocket 路由在chat/routing.py中注册 WebSocket 路由让 Channels 知道把ws/chat/room/的请求交给RoomConsumerfrom django.urls import re_path from . import consumers websocket_urlpatterns [ re_path(rws/chat/room/$, consumers.RoomConsumer.as_asgi()), ]然后在项目的asgi.py中用ProtocolTypeRouter把 HTTP 与 WebSocket 路由组合起来。至此后端已经具备加入房间、发送消息、订阅消息流和在线用户实时更新的全部能力。第六步编写页面视图与模板按官方教程docs/tutorial/part_2.rst的思路我们需要两个页面一个是输入房间名并创建/加入房间的首页index.html另一个是展示聊天记录的聊天室页面room.html。对应的views.py非常简单from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, render, reverse from .models import Room def index(request): if request.method POST: name request.POST.get(name, None) if name: room Room.objects.create(namename, hostrequest.user) HttpResponseRedirect(reverse(room, args[room.pk])) return render(request, chat/index.html) def room(request, pk): room get_object_or_404(Room, pkpk) return render(request, chat/room.html, {room: room})最后在chat/urls.py中注册path(, views.index)和path(room/int:pk/, views.room)两个路由。第七步前端 JavaScript 连接与联调测试一切就绪后在room.html中加入 WebSocket 客户端代码。连接建立后依次发送join_room、retrieve、subscribe_to_messages_in_room等 action即可完成加入房间、拉取历史消息和订阅实时推送const room_pk {{ room.pk }}; const request_id {{ request.sessions.session_key }}; const chatSocket new WebSocket(ws://${window.location.host}/ws/chat/room/); chatSocket.onopen function(){ chatSocket.send(JSON.stringify({pk: room_pk, action: join_room, request_id: request_id})); chatSocket.send(JSON.stringify({pk: room_pk, action: retrieve, request_id: request_id})); chatSocket.send(JSON.stringify({pk: room_pk, action: subscribe_to_messages_in_room, request_id: request_id})); }; chatSocket.onmessage function(e) { const data JSON.parse(e.data); if (data.action create) { // 追加一条新消息到聊天窗口 console.log(新消息:, data.data); } };发送消息时只需一条指令chatSocket.send(JSON.stringify({ message: $(#chat-message-input).val(), action: create_message, request_id: request_id }));启动开发服务器打开两个浏览器标签页进入同一个房间在其中一个发消息另一个页面无需刷新即可实时收到进阶玩法不止于聊天室掌握这 7 步之后你已经能驾驭 djangochannelsrestframework 的核心能力。DCRF 还提供了更多实用特性CRUD Mixin 全家桶ListModelMixin、CreateModelMixin、RetrieveModelMixin、UpdateModelMixin、PatchModelMixin、DeleteModelMixin定义在djangochannelsrestframework/mixins.py客户端直接发送{action: list, request_id: 42}即可触发对应操作权限控制从djangochannelsrestframework.permissions导入IsAuthenticated、AllowAny用法与 DRF 完全一致订阅自定义信号通过observer装饰器订阅 Django Signal实现任意业务事件的实时推送复用普通视图view_as_consumer可以让你把已有的 Django View 直接包装成 WebSocket Consumer迁移成本几乎为零如果你正在为项目引入实时通信能力djangochannelsrestframework 就是那个让你少写 80% 样板代码的宝藏框架。赶紧动手把上面的聊天室跑起来吧【免费下载链接】djangochannelsrestframeworkA Rest-framework for websockets using Django channels-v4项目地址: https://gitcode.com/gh_mirrors/dj/djangochannelsrestframework创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表