私信功能的通知处理器
来源:10-15 排错思路讲解与课后作业
Otiose
2021-05-10
老师,我在写本节课后作业中的私信功能的通知时,我把通知处理器写在如下发送私信函数中的倒数第三行:
@login_required
@ajax_required
@require_http_methods(["POST"])
def send_message(request):
sender = request.user
recipient_username = request.POST["to"]
recipient = get_user_model().objects.get(username=recipient_username)
message = request.POST["message"]
if len(message.strip()) != 0 and sender != recipient:
msg = Message.objects.create(
sender=sender,
recipient=recipient,
message=message
)
channel_layer = get_channel_layer()
payload = {
'type': 'receive',
'message': render_to_string('messager/single_message.html', {'message': msg}),
'sender': sender.username
}
async_to_sync(channel_layer.group_send)(recipient_username, payload)
notification_handler(sender, recipient, 'R', msg)
return render(request, 'messager/single_message.html', {"message": msg})
return HttpResponse()
但是测试报错:
'action_object': action_object.user.username,
AttributeError: 'Message' object has no attribute 'user'
通知处理器的代码与您后来修复bug后的代码一致:
def notification_handler(actor, recipient, verb, action_object, **kwargs):
key = kwargs.get('key', 'notification')
id_value = kwargs.get('id_value', None)
Notification.objects.create(
actor=actor,
recipient=recipient,
verb=verb,
action_object=action_object
)
channel_layer = get_channel_layer()
payload = {
'type': 'receive',
'key': key,
'actor_name': actor.username,
'action_object': action_object.user.username,
'id_value': id_value
}
async_to_sync(channel_layer.group_send)('notifications', payload)
也就是说'action_object': action_object.user.username
这行代码走不通,虽然说私信模型类中确实没有user字段,只有sender和recipient。也有可能是我的第四个参数action_object写错了,但是我看了半天确实应该是msg呀,麻烦老师指点一下。
写回答
2回答
-
请叫我滚去写代码
2021-07-02
私信通知功能代码:
在messager/views.py里的send_message方法里添加一行代码
notification_handler(sender, recipient, 'R', recipient)
添加后如下:
def send_message(request): """发送消息,ajax post请求""" sender = request.user # 发送方是当前登陆的用户 recipient_username = request.POST['to'] # 接收方是前端选择时传过来的参数 recipient = get_user_model().objects.get(username=recipient_username) # 查询接收方 # # recipient_pk = request.POST['to'] # 接收方是前端选择时传过来的参数 # recipient = get_user_model().objects.get(pk=recipient_pk) # 查询接收方 message = request.POST['message'] # 消息内容,前端传过来的 if len(message.strip()) != 0 and sender != recipient: # 消息内容去除两端空格后不等于0,且发送者不是接收者(不是自己给自己发) msg = Message.objects.create( sender=sender, recipient=recipient, message=message ) channel_layer = get_channel_layer() # 获取聊天组 payload = { 'type': 'receive', # 这里两个是固定的写法,receive是receive方法 'message': render_to_string('messager/single_message.html', {'message': msg}), 'sender': sender.username } # group_send(group:所在组-接收者的username, message: 消息内容) # 因为views.py里是同步,需要使用async_to_sync转为异步发送给consumer # print('3*' + recipient_username) # print('4*' + slugify(recipient_username)) # recipient_username 接收方 async_to_sync(channel_layer.group_send)(slugify(recipient_username), payload) # 通知 notification_handler(sender, recipient, 'R', recipient) return render(request, 'messager/single_message.html', {'message': msg}) return HttpResponse()
第二步:在notifications/views.py修改notification_handler方法添加if判断,修改及添加以下代码
if action_object == recipient: action_object_user = recipient.username else: action_object_user = action_object.user.username payload = { 'type': 'receive', # 固定写法,指的是consumer.py里的receive方法 'key': key, 'id_value': id_value, 'actor_name': actor.username, 'action_object': action_object_user }
修改完成后的样子:
def notification_handler(actor, recipient, verb, action_object, **kwargs): """ 通知处理器 :param actor: request.user对象, 前端传过来 :param recipient: User Instance 接收者实例,可以是一个或者多个接收者 :param verb: str 通知类别 :param action_object: Instance 动作对象的实例(比如news, articles, qa) :param kwargs: key, id_value等 :return: None """ key = kwargs.get('key', 'notification') id_value = kwargs.get('id_value', None) # 记录通知的内容,保存数据库s Notification.object.create( actor=actor, recipient=recipient, verb=verb, action_object=action_object ) channel_layer = get_channel_layer() if action_object == recipient: action_object_user = recipient.username else: action_object_user = action_object.user.username payload = { 'type': 'receive', # 固定写法,指的是consumer.py里的receive方法 'key': key, 'id_value': id_value, 'actor_name': actor.username, 'action_object': action_object_user }
30 -
Jack
2021-05-12
您好,action_object 是对象的作者。如果是文章,就只指文章的作者;如果是问题,就是问题的作者;但,如果是私信的话,就应该是私信的发送者sender
'action_object': action_object.user.username
这个时候上面的就不适用了,因为问题和文章都有user关联,而message只有sender。需要加个判断,改成 action_object.sender.username
012021-05-12
相似问题