无法获取配置文件对象名字

Posted

技术标签:

【中文标题】无法获取配置文件对象名字【英文标题】:can't get the profile object firstname 【发布时间】:2021-03-11 23:56:54 【问题描述】:

我正在尝试获取个人资料的名字,但它给了我这个错误

File "/home/marwan/Desktop/Gowd/venv/lib/python3.6/site-packages/django/utils/asyncio.py", line 24, in inner
    raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
WebSocket DISCONNECT /public_chat/1/ [127.0.0.1:53742]
INFO 2021-03-12 01:43:30,570 runserver 119412 140507688003328 WebSocket DISCONNECT /public_chat/1/ [127.0.0.1:53742]

我认为此错误与尝试在第 56 行获取用户配置文件有关

"profile":   self.scope["user"].profile.firstname,

如果我删除它会正常工作

这是我的 consumer.py 文件

from channels.generic.websocket import AsyncJsonWebsocketConsumer
import json
from django.contrib.auth import get_user_model
from gowd_project.users.models import User, Profile

User = get_user_model()


# Example taken from:
# https://github.com/andrewgodwin/channels-examples/blob/master/multichat/chat/consumers.py
class PublicChatConsumer(AsyncJsonWebsocketConsumer):

    async def connect(self):
        """
        Called when the websocket is handshaking as part of initial connection.
        """
        print("PublicChatConsumer: connect: " + str(self.scope["user"]))
        # let everyone connect. But limit read/write to authenticated users
        await self.accept()

        # Add them to the group so they get room messages
        await self.channel_layer.group_add(
            "public_chatroom_1",
            self.channel_name,
        )

    async def disconnect(self, code):
        """
        Called when the WebSocket closes for any reason.
        """
        # leave the room
        print("PublicChatConsumer: disconnect")
        pass

    async def receive_json(self, content):
        """
        Called when we get a text frame. Channels will JSON-decode the payload
        for us and pass it as the first argument.
        """
        # Messages will have a "command" key we can switch on
        command = content.get("command", None)
        print("PublicChatConsumer: receive_json: " + str(command))
        print("PublicChatConsumer: receive_json: message: " + str(content["message"]))
        if command == "send":
            if len(content["message"].lstrip()) == 0:
                raise Exception("You can't send an empty message.")
            await self.send_message(content["message"])

    async def send_message(self, message):
        await self.channel_layer.group_send(
            "public_chatroom_1",
            
                "type": "chat.message",
                "user_id": self.scope["user"].id,
                "user_name": self.scope["user"].name,
                "profile":   self.scope["user"].profile.firstname,
                "message": message,
            
        )

    async def chat_message(self, event):
        """
        Called when someone has messaged our chat.
        """
        # Send a message down to the client
        print("PublicChatConsumer: chat_message from user #" + str(event["user_id"]))
        await self.send_json(
            
                "user_id": event["user_id"],
                "user_name": event["user_name"],
                "message": event["message"],
            ,
        )

【问题讨论】:

这是 full 堆栈跟踪吗?如果删除该行使其正常工作,那么错误很清楚地表明您正在尝试那里的东西——我猜数据库调用来获取配置文件对象——在异步方法中是不允许的。我不知道self.scope["user"] 是如何被填充的,但如果您可以控制它,使用select_related 与用户一起获取配置文件数据可能会解决您的问题。此外,如果您要重置它,则不应导入用户。 我认为这是正确的,它不允许在异步方法中,所以你建议我在这种情况下谁可以获取用户配置文件?你能更清楚一点吗,因为我对这些东西不熟悉 错误消息建议您“使用线程或sync_to_async”来解决这个问题。您应该对此进行调查并查看在我的第一条评论中链接的select_related,看看其中任何一个是否适合您。我不知道哪种方法(如果有的话)适合您的情况,因此您需要根据自己的要求进行研究。 【参考方案1】:

sync_to_async 接受一个可调用对象,而不是结果。所以,我需要这样做:

@sync_to_async
    def get_user_profile(self, user):
        return user.profile

    async def send_message(self, message):
        profile = await PublicChatConsumer.get_user_profile(self.scope["user"])
        profile_name = profile.firstname
        await self.channel_layer.group_send(
            "public_chatroom_1",
            
                "type": "chat.message",
                "user_id": self.scope["user"].id,
                "username": profile_name,
                "message": message,
            
        )

full documentation Similar problem

【讨论】:

以上是关于无法获取配置文件对象名字的主要内容,如果未能解决你的问题,请参考以下文章

IDEA hibernate xml配置文件中表名字段报红,无法通过点击表名跳转到数据库表

IDEA hibernate xml配置文件中表名字段报红,无法通过点击表名跳转到数据库表

放大:无法获取配置文件:缺少配置文件配置:未定义

电脑显示无法获取用户配置文件怎么回事?

idea 中配置文件为 File 类型,无法修改为 xml

java spring 获取配置文件,并放入一个list 对象中