如何在Django中通知用户管理员创建的事件?
我们现在正在为一个组织开发一个系统。其中一个需求是,当管理员创建一个事件时,要通知用户。所有网站用户都应该收到通知,但不是通过电子邮件,而是类似于Facebook的通知。我们该如何在Django中实现这个功能,而不使用Django-notifications、Django-activity streams等工具呢?我们对Django还很陌生,希望能尽可能简单地实现这个功能。希望大家能帮帮我们。谢谢大家!
2 个回答
@Zayatzz 我们计划只通知用户一次。不过在用户查看了通知后,他/她可以在之后再次查看。
在这种情况下,你可能需要在后台创建通知对象。这个对象大概需要长这样:
class Notification(models.Model):
message = models.TextField()
type = models.IntegerField()
relevancy_end_date = models.DateField()
notified_users = models.ManyToManyField(django.contrib.auth.User, null = True)
在你的后台表单中,你需要重写那个模型的整数字段,让它有选择项。你可以从这里获取选择项:
https://docs.djangoproject.com/en/dev/ref/contrib/messages/#creating-custom-message-levels
这些选择项基本上是一些数字,比如 10、20、30、40、50。
在视图中,你可以检查是否有用户需要被通知的消息:
notes = Notification.objects.filter(notified_users__id = request.user.id).filter(relevancy_end_date__gte = datetime.datetime.now())
如果有通知,就用 Django 自带的消息框架来创建这些消息:
from django.contrib import messages
if notes:
for note in notes:
messages.add_message(request, note.type, 'Hello world.')
note.notified_users.add(request.user)
消息的类型(信息、错误、成功)会保存在你的通知类型列中。所以是的,你需要在这里添加一些检查,根据通知类型来变化消息类型。
不过在每个想要显示消息的视图开头写这个代码并不是很简洁。所以你应该为此创建一个自己的视图装饰器。
这两个链接应该能帮助你做到这一点: https://docs.djangoproject.com/en/dev/topics/http/decorators/ 如何在 Django 中创建装饰器来装饰视图
现在,如果有用户需要被通知的消息,它会在由消息框架处理的请求中。要在视图中显示它,你需要这样做: https://docs.djangoproject.com/en/dev/ref/contrib/messages/#displaying-messages
或者,正如 Brandon 所说,如果你希望消息通过 ajax/json 调用来发送,那么你需要“手动”处理它们,并将它们插入到 json 响应中。像这样:
https://docs.djangoproject.com/en/dev/ref/contrib/messages/#expiration-of-messages
from django.utils import simplejson
feedback = messages.get_messages(request)
for message in feedback:
response[message.tags] = response.get(message.tags, [])
message_text = smart_str(message.message, encoding='utf-8', strings_only=True)
response[message.tags].append(message_text)
return simplejson.dumps(response)
在你有了通知对象和视图装饰器之后,你只需要创建一个视图来显示用户已经看到的通知。我相信你能搞定如何创建那个查询。
你还可以调整这个通知类,增加一个额外的布尔字段,或者用 relevancy_end_date 字段来替代,以便更容易地开启或关闭。
注意!这段代码完全没有经过测试,可能会出现一些错误,但这是一个可以让你朝着正确方向前进的起点,我觉得根据你的输入,这可能是对你最好的建议。
Alan
所以,我只能给你一些大概的方向,因为我不太清楚具体情况,但基本上你可以这样做:
首先,我建议你在你的管理类中添加一个对save_model()方法的重写。这是你可以检查你的对象是否已经有主键的地方。如果没有,你可以设置一个标志来创建事件(我不太确定你是否还需要通过外键将事件和通知关联起来)。
如果你不需要将事件和通知关联在一起,你可以直接在需要的时候创建通知对象,而不必设置标志。
其次,创建一个视图,用来返回你的事件的JSON格式数据。我不太确定你需要如何过滤这些对象,比如是否只针对登录用户等,但你只想返回那些之前没有被查看过的事件。
第三,通过ajax定时调用这个视图,传入你需要的过滤条件,并记录通知已经被查看。
希望这些能帮到你。