【问题标题】:How it should be done properly to send and receive message with user ID using websockets in Django and Angular?如何在 Django 和 Angular 中使用 websockets 发送和接收带有用户 ID 的消息?
【发布时间】:2017-09-27 10:17:09
【问题描述】:

我将使用 websockets 创建聊天机器人。每个用户都可以拥有自己的帐户。我有用 Angular 编写的 Django 后端和前端。目前我对消息对象有疑问。也就是说,我在后端得到了这个:

django_1  | django.db.utils.IntegrityError: null value in column "user_id" violates not-null constraint
django_1  | DETAIL:  Failing row contains (212, {"message":"Hello"}, null).

看起来我不会从前端发送用户 ID。也许我应该发送类似{"message":"Hello", "id":1} 的东西?我想知道我该如何解决它以及应该如何正确地完成它?

我的 Django 消息模型是这样的:

class Message(models.Model):
    user = models.ForeignKey('auth.User')
    message = models.CharField(max_length=200)

这是我的后端消费者:

@channel_session_user_from_http
def msg_consumer(message):
    text = message.content.get('text')
    Message.objects.create(
        message=text,
    )
    Group("chat").send({'text': text})

@channel_session_user
def ws_connect(message):
    # Accept the connection
    message.reply_channel.send({"accept": True})
    # Add to the chat group
    Group("chat").add(message.reply_channel)

    message.reply_channel.send({
        "text": json.dumps({
            'message': 'Welcome'
        })
    })

@channel_session_user
def ws_receive(message):

    message.reply_channel.send({"accept": True})
    print("Backend received message: " + message.content['text'])
    Message.objects.create(
        message = message.content['text'],
    )

    Channel("chat").send({
        "text": json.dumps({
             'message': 'Can we start?'
         })
    })

@channel_session_user
def ws_disconnect(message):
    Group("chat").discard(message.reply_channel)

这是我的 Angular 组件的一部分:

export class HomeComponent {

    response: string;
    response2: string;

    constructor(
        private chatService: ChatService,
        private router: Router,
        private http: Http,
    ) {

        chatService.messages.subscribe(msg => {
            this.response = msg.message;
      console.log("Response from backend: " + msg.message);
        });

    }
    private message = {
        message: 'this is a test message'
    }

  sendMsg() {
        console.log('new message from client to websocket: ', this.message);
        this.chatService.messages.next(this.message);
        return this.message.message;
    }

  send(msg) {
     this.message.message = msg;
     this.sendMsg();
  }

      login() {
        return this.http.get('/data', )
            .map(response => response.json())
            .subscribe(response2 => this.response2 = response2);
    }


}

@Component({
  selector: 'key-up3',
  template: `
    <input #box (keyup.enter)="keyup7.emit(box.value)">
    <p>{{value}}</p>
  `
})
export class KeyUpComponent_v3 {
   @Output() keyup7 = new EventEmitter<string>();
}

更新 目前我在后端以下面显示的方式解决了它。

def ws_receive(消息):

message.reply_channel.send({"accept": True})
print("Backend received message: " + message.content['text'])
data = json.loads(message.content['text'])

Message.objects.create(
    user_id=data['user_id'],
    message = data['message'],
)

【问题讨论】:

    标签: python django angular python-3.x typescript


    【解决方案1】:

    错误似乎表明您的Message 实例是在没有user_id 的情况下创建的。 如果在创建新的Message 实例时添加此参数会怎样?

    @channel_session_user_from_http
    def msg_consumer(message):
        text = message.content.get('text')
        Message.objects.create(
            user=message.user,  # <- Here is the user associated
            message=text,
        )
        Group("chat").send({'text': text})
    

    【讨论】:

    • 我知道我应该发送这样的正文{"message":"Hello", "id":1}?或者也许应该以其他方式完成?
    • 我不知道,我不确定您的错误是否与您必须发送的频道或 json 正文有关。但是您的模型Messageuser 声明为没有is_null=True 的外键字段。由于默认情况下is_null=False,因此您必须在创建任何Message 实例时提供用户实例(或用户pk)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 2011-07-05
    • 2015-01-16
    • 1970-01-01
    • 2011-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多