繁体   English   中英

Django 通道:将表单数据传递给消费者

[英]Django channels: pass form data to consumer

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

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

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

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的原因。 但我不确定这是否是最好的解决方案......

这会帮助你。

消费者.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 发送消息

通常,您可以通过以下方式从外部代码中调用使用者中的方法:

from channels.layers import get_channel_layer
channel_layer = get_channel_layer()

await self.channel_layer.send(
            '<channel_name>',
            {
                'type': '<method_name>',
            }
        )

但是如您所见,这要求您指定仅在客户端连接后才能获得的频道名称。 换句话说,您不应尝试调用connect,而应使用使用者中的其他方法。 同样,您的客户端应首先连接到网络套接字,然后再最终访问它。 我不完全理解您的用例,但我希望这能给您一个思路

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM