مساء الخير أيها الأصدقاء. تحسبا لبدء دورة
Python Web Developer ، فإننا نشارك تقليديا ترجمة مفيدة لك.

تشاهد دليلًا أمامك يوضح لك كيفية إنشاء تطبيق دردشة في Python و Django و React.على عكس الأدلة الأخرى ، لا أستخدم Python و Django لاتصالات WebSocket. على الرغم من أن هذا يبدو رائعًا من الناحية الفنية ، إلا أنه يعمل ببطء شديد ومكلفة في حد ذاته ، خاصةً إذا كان لديك عدد لا بأس به من المستخدمين. تقوم لغات مثل C ++ و Go و Elixir بعمل أفضل بكثير من جوهر الدردشة.
في هذا البرنامج التعليمي ، سوف نستخدم Stream ،
واجهة برمجة تطبيقات للدردشة تعتني باتصالات WebSocket وغيرها من الجوانب الثقيلة باستخدام Go و Raft و RocksDB.
المحتويات:
- الرد على واجهة الدردشة التجريبية
- تثبيت جانغو / بيثون
- إذن المستخدم
- جانغو بقية الإطار
- إنشاء رمز للوصول إلى خادم الدردشة Stream
- رد فعل التكامل التكامل
- إرسال الرسائل من خادم Python
- الأفكار الأخيرة
مستودع جيثب مع رمز من مقال
لنبدأ!
الخطوة 1: رد فعل واجهة الدردشة التجريبية
قبل أن نبدأ في التفكير في جزء Python ، لننشر واجهة بسيطة على React حتى يكون لدينا شيء جميل ومرئي:
$ yarn global add create-react-app $ brew install node && brew install yarn
يستعاض عن الكود في
src/App.js
بما يلي:
import React from "react"; import { Chat, Channel, ChannelHeader, Thread, Window } from "stream-chat-react"; import { MessageList, MessageInput } from "stream-chat-react"; import { StreamChat } from "stream-chat"; import "stream-chat-react/dist/css/index.css"; const chatClient = new StreamChat("qk4nn7rpcn75"); // Demo Stream Key const userToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiY29vbC1za3ktOSJ9.mhikC6HPqPKoCP4aHHfuH9dFgPQ2Fth5QoRAfolJjC4"; // Demo Stream Token chatClient.setUser( { id: "cool-sky-9", name: "Cool sky", image: "https://getstream.io/random_svg/?id=cool-sky-9&name=Cool+sky" }, userToken ); const channel = chatClient.channel("messaging", "godevs", { // image and name are required, however, you can add custom fields image: "https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png", name: "Talk about Go" }); const App = () => ( <Chat client={chatClient} theme={"messaging light"}> <Channel channel={channel}> <Window> <ChannelHeader /> <MessageList /> <MessageInput /> </Window> <Thread /> </Channel> </Chat> ); export default App;
الآن ، استخدم أمر
yarn start
لمشاهدة الدردشة في العمل!
الخطوة 2: تثبيت Django / Python (تخطي هذه الخطوة إذا كان لديك بالفعل كل ما تحتاجه)
تأكد من أن لديك Python 3.7 وأنه يعمل:
$ brew install python3 $ pip install virtualenv virtualenvwrapper $ export WORKON_HOME=~/Envs $ source /usr/local/bin/virtualenvwrapper.sh $ mkvirtualenv chatexample -p `which python3` $ workon chatexample
إذا لم ينجح ذلك ، فجرّب الرمز التالي:
$ python3 -m venv chatexample $ source chatexample/bin/activate
الآن بعد أن أصبحت في بيئتك الافتراضية ، سترى بيثون 3 عند بدء التشغيل:
$ python --version
لإنشاء مشروع جديد في Django ، استخدم الكود التالي:
$ pip install django $ django-admin startproject mychat
وتشغيل التطبيق:
$ cd mychat $ python manage.py runserver
الآن عند فتح
http://localhost:8000
، سترى ما يلي:

الخطوة 3: إذن المستخدم
والخطوة التالية هي تكوين إذن المستخدم في جانغو.
$ python manage.py migrate $ python manage.py createsuperuser $ python manage.py runserver
انتقل إلى
http://localhost:8000/admin/
وقم بتسجيل الدخول. فويلا!
سترى علامة تبويب المسؤول مماثلة لتلك الموجودة أدناه:

الخطوة 4: جانغو بقية الإطار
أحد حزمي المفضلة لدمج React مع Django هو إطار Django Rest Framework. لجعلها تعمل ، تحتاج إلى إنشاء نقاط النهاية ل:
- تسجيل المستخدم
- تسجيل دخول المستخدم.
يمكننا أن نجعلهم بأنفسنا ، ولكن هناك حزمة تسمى
Djoser التي تحل هذه المشكلة. سيقوم بتكوين نقاط النهاية API اللازمة لتسجيل المستخدم ، تسجيل الدخول ، إعادة تعيين كلمة المرور ، إلخ.
لتثبيت Djoser ، استخدم ما يلي:
$ pip install djangorestframework djoser
بعد ذلك ، قم بتحرير
urls.py
وقم بتغيير محتويات الملف كما يلي:
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('auth/', include('djoser.urls')), path('auth/', include('djoser.urls.authtoken')), ]
عند الانتهاء ، قم بتحرير
settings.py
وإجراء التغييرات:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'rest_framework.authtoken', 'djoser', ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication', ) }
لمزيد من المعلومات حول نقاط النهاية API التي يوفرها Djoser ، راجع ما يلي:
https://djoser.readthedocs.io/en/latest/sample_usage.htmlالآن دعنا نستمر ونختبر نقطة نهاية التسجيل:
$ curl -X POST http://127.0.0.1:8000/auth/users/ --data 'username=djoser&password=alpine12'
الخطوة 5: إنشاء الرموز للوصول إلى خادم دفق الدردشة
نحن الآن بحاجة إلى تكوين طرق عرض Djoser لإنشاء رموز مميزة. لذلك دعونا نبدأ.
لننظم ملفاتنا قليلاً وننشئ مجلد تطبيق دردشة في مشروعنا (تأكد من أنك في الدليل الصحيح):
$ python manage.py startapp auth
تثبيت دردشة البث المباشر:
$ pip install stream-chat
أنشئ مُسلسل مخصص في
auth/serializers.py
باستخدام المنطق التالي:
from djoser.serializers import TokenSerializer from rest_framework import serializers from djoser.conf import settings as djoser_settings from stream_chat import StreamChat from django.conf import settings class StreamTokenSerializer(TokenSerializer): stream_token = serializers.SerializerMethodField() class Meta: model = djoser_settings.TOKEN_MODEL fields = ('auth_token','stream_token') def get_stream_token(self, obj): client = StreamChat(api_key=settings.STREAM_API_KEY, api_secret=settings.STREAM_API_SECRET) token = client.create_token(obj.user.id) return token
أخيرًا ، استخدم برنامج تسلسلي مخصص لتحديث ملف
settings.py
:
STREAM_API_KEY = YOUR_STREAM_API_KEY
أعد تشغيل الترحيل:
$ python manage.py migrate
للتحقق من أنه يعمل ، انتقل إلى نقطة النهاية باستخدام طلب POST:
$ curl -X POST http://127.0.0.1:8000/auth/token/login/ --data 'username=djoser&password=alpine12'
يجب العودة
auth_token
و
stream_token
.
الخطوة 6: دمج إذن التفاعل
لأسباب واضحة ، تعد إضافة ترخيص إلى الواجهة الأمامية خطوة مهمة. في حالتنا ، يعد هذا مفيدًا بشكل خاص ، حيث يمكننا استخراج الرمز المميز للمستخدم من واجهة برمجة التطبيقات (التي تعمل على Python) واستخدامه بشكل حيوي عند إرسال الرسائل.
أولاً ، قم بتثبيت CORS ، حزمة الوسيطة لـ Django:
$ pip install django-cors-headers
ثم قم بتعديل ملف
settings.py
للإشارة إلى
djors-cors-header
:
INSTALLED_APPS = ( ... 'corsheaders', ... ) MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... ]
أخيرًا ، أضف ما يلي إلى ملف
settings.py
:
CORS_ORIGIN_ALLOW_ALL = True
ستتطلب الخطوة التالية بعض التغييرات على واجهتك. للبدء ، ستحتاج إلى التأكد من تثبيت جميع التبعيات من خلال الغزل:
$ yarn add axios react-dom react-router-dom
بعد ذلك ، قم بإنشاء الملفات التالية في
src/
directory:
- AuthedRoute.js
- UnauthedRoute.js
- withSession.js
- Login.js
- Chat.js
App.js
import React from "react"; import { BrowserRouter as Router, Switch } from "react-router-dom"; import Chat from "./Chat"; import Login from "./Login"; import UnauthedRoute from "./UnauthedRoute"; import AuthedRoute from "./AuthedRoute"; const App = () => ( <Router> <Switch> <UnauthedRoute path="/auth/login" component={Login} /> <AuthedRoute path="/" component={Chat} /> </Switch> </Router> ); export default App;
AuthedRoute.js
import React from "react"; import { Redirect, Route } from "react-router-dom"; const AuthedRoute = ({ component: Component, loading, ...rest }) => { const isAuthed = Boolean(localStorage.getItem("token")); return ( <Route {...rest} render={props => loading ? ( <p>Loading...</p> ) : isAuthed ? ( <Component history={props.history} {...rest} /> ) : ( <Redirect to={{ pathname: "/auth/login", state: { next: props.location } }} /> ) } /> ); }; export default AuthedRoute;
UnauthedRoute.js
import React from "react"; import { Redirect, Route } from "react-router-dom"; const AuthedRoute = ({ component: Component, loading, ...rest }) => { const isAuthed = Boolean(localStorage.getItem("token")); return ( <Route {...rest} render={props => loading ? ( <p>Loading...</p> ) : !isAuthed ? ( <Component history={props.history} {...rest} /> ) : ( <Redirect to={{ pathname: "/" }} /> ) } /> ); }; export default AuthedRoute;
withSession.js
import React from "react"; import { withRouter } from "react-router"; export default (Component, unAuthed = false) => { const WithSession = ({ user = {}, streamToken, ...props }) => user.id || unAuthed ? ( <Component userId={user.id} user={user} session={window.streamSession} {...props} /> ) : ( <Component {...props} /> ); return withRouter(WithSession); };
Login.js
import React, { Component } from "react"; import axios from "axios"; class Login extends Component { constructor(props) { super(props); this.state = { loading: false, email: "", password: "" }; this.initStream = this.initStream.bind(this); } async initStream() { await this.setState({ loading: true }); const base = "http://localhost:8000"; const formData = new FormData(); formData.set("username", this.state.email); formData.set("password", this.state.password); const registration = await axios({ method: "POST", url: `${base}/auth/users/`, data: formData, config: { headers: { "Content-Type": "multipart/form-data" } } }); const authorization = await axios({ method: "POST", url: `${base}/auth/token/login/`, data: formData, config: { headers: { "Content-Type": "multipart/form-data" } } }); localStorage.setItem("token", authorization.data.stream_token); await this.setState({ loading: false }); this.props.history.push("/"); } handleChange = e => { this.setState({ [e.target.name]: e.target.value }); }; render() { return ( <div className="login-root"> <div className="login-card"> <h4>Login</h4> <input type="text" placeholder="Email" name="email" onChange={e => this.handleChange(e)} /> <input type="password" placeholder="Password" name="password" onChange={e => this.handleChange(e)} /> <button onClick={this.initStream}>Submit</button> </div> </div> ); } } export default Login;
Chat.js
import React, { Component } from "react"; import { Chat, Channel, ChannelHeader, Thread, Window } from "stream-chat-react"; import { MessageList, MessageInput } from "stream-chat-react"; import { StreamChat } from "stream-chat"; import "stream-chat-react/dist/css/index.css"; class App extends Component { constructor(props) { super(props); this.client = new StreamChat("<YOUR_STREAM_APP_ID>"); this.client.setUser( { id: "cool-sky-9", name: "Cool Sky", image: "https://getstream.io/random_svg/?id=cool-sky-9&name=Cool+sky" }, localStorage.getItem("token") ); this.channel = this.client.channel("messaging", "godevs", { image: "https://cdn.chrisshort.net/testing-certificate-chains-in-go/GOPHER_MIC_DROP.png", name: "Talk about Go" }); } render() { return ( <Chat client={this.client} theme={"messaging light"}> <Channel channel={this.channel}> <Window> <ChannelHeader /> <MessageList /> <MessageInput /> </Window> <Thread /> </Channel> </Chat> ); } } export default App;
تأكد من استبدال
YOUR_STREAM_APP_ID
بمعرف تطبيق البث
YOUR_STREAM_APP_ID
، والذي يمكن العثور عليه على
لوحة القيادة .
أعد تشغيل التطبيق على الواجهة الأمامية وسترى التفويض! أدخل عنوان البريد الإلكتروني وكلمة المرور ، وسيتم طلب الرمز المميز وتخزينه في التخزين المحلي.
الخطوة 7: إرسال الرسائل من خادم بيثون
إذا أردت فجأة إنشاء واجهة برمجة تطبيقات للدردشة باستخدام الواجهة الخلفية في Python ، فهناك أمر خاص يمكنك استخدامه.
تأكد من أن التطبيقات المثبتة تبدو هكذا في
settings.py
:
INSTALLED_APPS = [ 'corsheaders', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'rest_framework.authtoken', 'djoser', ]
بعد ذلك ، قم بإنشاء دليل الدردشة / الإدارة / الأوامر. في هذا الدليل ، أضف ملفًا باسم
broadcast.py
بالمحتويات التالية:
from django.core.management.base import BaseCommand, CommandError from django.conf import settings from stream_chat import StreamChat class Command(BaseCommand): help = 'Broadcast the message on your channel' def add_arguments(self, parser): parser.add_argument('--message') def handle(self, *args, **options): client = StreamChat(api_key=settings.STREAM_API_KEY, api_secret=settings.STREAM_API_SECRET) client.update_user({"id": "system", "name": "The Server"}) channel = client.channel("messaging", "kung-fu") channel.create("system") response = channel.send_message({"text": "AMA about kung-fu"}, 'system') self.stdout.write(self.style.SUCCESS('Successfully posted a message with id "%s"' % response['message']['id']))
يمكنك محاولة إرسال رسالة دردشة على النحو التالي:
$ python manage.py broadcast --message hello
وسترى هذا الرد:

الأفكار الأخيرة
أتمنى أن تستمتع بهذا البرنامج التعليمي حول إنشاء تطبيق دردشة في جانغو وبيثون ورياكت!
للقيام بجولة تفاعلية في
Stream Chat ، يرجى إلقاء نظرة على دليلنا حول إنشاء
واجهة برمجة التطبيقات على موقع Stream . إذا كنت تستمتع بالحفر في الكود الخاص بمكونات Stream Chat React ، فيمكنك العثور على الوثائق الكاملة
هنا . إذا كنت ترغب في إنشاء دردشة على Stream ، يسعدنا أن نقدم العديد من
أدوات تطوير البرامج (SDK) للغات والأطر الشائعة حتى أحدث إصدار من
iOS (Swift) .
هذا كل شيء. نراكم في
الندوة المفتوحة على Django ORM Tricks .