首页 > 解决方案 > Django 频道:将表单数据传递给消费者

问题描述

我正在学习 Django,我正在一个网页上工作,我需要为用户提供登录外部服务的可能性。我不能简单地使用传统的 Django 视图系统,否则我会因为简单的刷新而失去连接。出于这个原因,我考虑使用Django Channels

我现在的问题是如何将数据发送到消费者类?使用教程consumers.py中给出的内容,我想将表单提交中的数据发送到函数,然后在登录到外部服务正常的情况下建立连接。然后,在那种情况下,我可以使用这些外部服务中的实例和方法。connectclient

那么,简而言之,是否可以向消费者发送表单数据?对于敏感数据的安全性,这可以吗?

from channels.generic.websocket import AsyncWebsocketConsumer
import json

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):

        ######
        ## login to external service
        ######

        #get login data from form submited when the websockted is initiated
        username = ...
        pass = ...

        self.client = Client(username, password)
        if  client:       
            await self.accept()

    # Receive message from room group
    async def chat_message(self, event):
        message = event['message']

        self.client.send(event['message'])

更新:

To clear the explanation: I can't save the user username and pass of the external service, and that I want to offer the user the possibility to use this [sms service](https://clxcommunications.github.io/sdk-xms-python/tutorial.html) with a text field and phone number.

所以问题是,即使我创建了一个表单以及用户名和密码来登录(在视图中)

client = clx.xms.Client('myserviceplan', 'mytoken')

然后在下一个请求中,我会丢失该client实例。这就是为什么我想Django Channels。但我不确定这是否是最好的解决方案......

标签: pythondjangochatdjango-channels

解决方案


这将对您有所帮助。

消费者.py

from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
import json

class EventConsumer(WebsocketConsumer):
    def connect(self):
        # self.room_name = self.scope['url_route']['kwargs']['room_name']
        # self.room_group_name = 'chat_%s' % self.room_name
        self.room_name = 'event'
        self.room_group_name = self.room_name+"_sharif"
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )
        print(self.room_group_name)
        self.accept()
        print("#######CONNECTED############")

    def disconnect(self, code):
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )
        print("DISCONNECED CODE: ",code)

    def receive(self, text_data=None, bytes_data=None):
        print(" MESSAGE RECEIVED")
        data = json.loads(text_data)
        message = data['message']
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,{
                "type": 'send_message_to_frontend',
                "message": message
            }
        )
    def send_message_to_frontend(self,event):
        print("EVENT TRIGERED")
        # Receive message from room group
        message = event['message']
        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': message
        }))

然后从您的应用程序外部/任何地方调用该函数,例如

def event_triger():
    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        'event_sharif',
        {
            'type': 'send_message_to_frontend',
            'message': "event_trigered_from_views"
        }
    ) 
# here 'event_sharif' is your room_group_name as i defined before in consumer
# 'type' is like a command, for which method you wants to trigger in your consumer

有关更多信息,您可以查看使用来自 Consumer 类外部的 Django Channels 发送消息


推荐阅读