[英]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
的原因。 但我不确定这是否是最好的解决方案......
这会帮助你。
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.