【Django2.0学习笔记】44.站内消息通知

44、站内消息通知(Part1)

1、为什么需要站内消息通知

  • 1)弥补发送邮件通知的不足
    • 邮件发送不了
    • 邮件被归为垃圾邮件
    • 用户不能登录邮箱
  • 2)形成较为完整的体验
    在这里插入图片描述

2、要实现什么功能

  • 1)消息中心
  • 2)什么情况需要通知
    • 评论/回复发送消息通知被评论的人
    • 点赞发送消息通知被点赞的人
    • 用户注册发送消息
    • (更多,例如公告…)
  • 3)点击消息,跳转到对应页面
    在这里插入图片描述

这次课主要实现上面三个功能,那么要怎么去实现呢,这些消息都是具体的一条条数据,是需要保存到数据库的,随时可以去查看,这样的话,我们就需要创建一个app创建一个model去记录 然后还要去实现发送消息接收消息这些功能。这里我们不用自己写,而是选择用一个第三方库去实现这些功能

3、django-notifications-hq

  • django-notifications-hq,是一款和Github通知相似的Django第三方库
  • 使用如下命令安装:pip install django-notifications-hq
  • 基本结构:发送人,接收人(一个或多个),动作(简单内容),详细消息
    在这里插入图片描述

官方文档:django-notifications

打开虚拟环境,输入pip install django-notifications-hq进行安装,可以看到会多出django-notifications-hq、django-model-utils、jsonfield这三个库
在这里插入图片描述
然后将Django Notifications添加到项目中,将应用程序通知添加到INSTALLED_APPS和urlconf中。
打开mysite/settings/base.py,注册应用,修改如下:
在这里插入图片描述
打开mysite/urls.py,加到路由中,修改如下:
在这里插入图片描述
接着,应用迁移文件,在命令行输入python manage.py migrate notifications,这是专门指定应用哪个app里面的迁移文件,如果我们不写app名称也是可以的
在这里插入图片描述

接着就是怎么使用,我们一个个来实现这些功能

第一个,创建一个消息中心页面
这功能肯定需要一个入口,我们可以在右侧下拉菜单中加一个消息中心
在底层模板页面base.html中加多一条,修改如下:
在这里插入图片描述
启动服务,刷新页面(其实这里,下拉菜单的“个人资料”里就有修改密码的功能,所以下拉菜单里面的“修改密码”这栏,我们可以去掉,即可以删除base.html里面对应的这一行代码)
在这里插入图片描述
接着我们开始写“我的消息”这部分页面的功能
我们现在base.html这里对应的href定义一个url链接:
在这里插入图片描述
然后在mysite/urls.py中加多一条路由,并写好对应的处理方法:
在这里插入图片描述
接着到 views 里面添加这个处理方法,修改 mysite/views.py 如下,返回一个模板页面:
在这里插入图片描述
现在我们来添加这个模板页面 my_notifications.html 如下,在公共位置templates下,新建,写入如下代码:

<!-- C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\templates\my_notifications.html -->
{% extends 'base.html' %}
{% load static %}

{% block title %}
	我的网站 | 我的消息
{% endblock %}

{% block nav_home_active %}active{% endblock %}

{% block header_extends %}
	<link rel="stylesheet" href="{% static 'my_notifications.css' %}">
{% endblock %}

{% block content %}
	
{% endblock %}

刷新页面:
在这里插入图片描述
接着我们要把消息罗列出来,显示到这个页面,那我们怎么去使用这个第三方库,把关于“我的消息”全部拿出来呢,查看官方文档
在这里插入图片描述
我们可以打开安装的这个库里面的具体代码查看
mysite_env/Lib/site_packages/notifications/base/models.py里面,我们看到对应的unread()方法

我们可以在my_notifications.html里去添加,修改如下,all表示取到已读和未读的所有消息:
在这里插入图片描述
刷新页面
在这里插入图片描述
接着修改my_notifications.html,将消息一条条罗列出来:
在这里插入图片描述
刷新页面,可以看到显示“暂无消息”
在这里插入图片描述

我们在后台管理添加几条消息,用来测试
在这里插入图片描述
在这里插入图片描述
Recipient:接收者
Actor content type:发送者。这里我们选择“用户”自己发送消息给自己
Actor object id:
Verb:内容
在这里插入图片描述

保存,接着看一下“我的消息”,可以看到如下内容,这是因为在mysite_env/Lib/site_packages/notifications/base/models.py中返回的是一个字符串:用户名actor+消息内容verb+时间timesince
在这里插入图片描述
在这里插入图片描述
我们接着修改my_notifications.html如下:
在这里插入图片描述
刷新页面
在这里插入图片描述

到这里为止,消息中心的页面已经创建完毕,
接下来我们要继续使用第三方库去实现其他功能

第二个,评论/回复发送消息通知被评论的人
在这里插入图片描述
需要修改comment/views.py如下:
其中notify.send(user, recipient=user, verb='you reached level 10'), 参数:发送者、接收者、内容
其中recipient(接收者),可以是一个也可以是多个,可能是评论一篇博客,也可能是回复评论,所以需要做一个判断是评论还是回复,
如果是评论的话,需要找到评论的主体(我们这里是博客)comment.content_object ,接收者是里面的用户comment.content_object.user,用户一般是user,但也可能不是user,所以我们最好自己定义一个get_user方法,而不是它自带的。既然是需要自定义的,我们就需要给它我们所用的对象models里面加一条,修改blog/models.py如下。
如果是回复,接收者则是reply_to
在这里插入图片描述
修改mysite\comment\views.py如下:
在这里插入图片描述
在这里插入图片描述

# 发送站内消息
if comment.reply_to is None: # 如果reply_to是None的话,那么就是评论,否则就是回复
	# 评论
	# 如果是评论的话,需要找到评论的主体(我们这里是博客)
	recipient = comment.content_object.get_user()
	if comment.content_type.model == 'blog':
		blog = comment.content_object
		verb = '{0} 评论了你的 《{1}》'.format(comment.user.get_nickname_or_username(), blog.title)
	else:
		raise Exception('unknow comment object type')
else:
	# 回复
	recipient = comment.reply_to
	verb = '{0} 回复了你的评论“{1}”'.format(
			comment.user.get_nickname_or_username(), 
			strip_tags(comment.parent.text)
		)

notify.send(comment.user, recipient=recipient, verb=verb, action_object=comment) # 参数:发送者、接收者(可以是一个也可以是多个,可能是评论一篇博客,也可能是回复评论,所以需要做一个判断是评论还是回复)、内容、触发的位置

修改完成之后,重启服务,刷新页面,我们评论一下某篇博客,然后回复下这个评论。点开“我的消息”,可以看到消息通知列表里面就有了这条评论和回复
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

虽然我们功能实现了,但是评论功能这部分代码就变得很复杂,除了保存评论之外,还要发送站内消息、发送邮件通知、再返回内容。随着功能越来越多,代码就越来越复杂,这种情况下,第三方库和评论app的联系就越来越紧密,如果我们不用这个第三方库而把它删掉,那评论这里代码的更改,维护程度比较高。所以这个第三方库是不太建议我们用这种方法的,它是建议signal发送信号这种方式
在这里插入图片描述

4、Signals

Django包含一个“信号调度程序”
它有助于在框架中的其他位置发生操作时通知分离的应用程序。
“降低耦合性”
在这里插入图片描述

我们可以查看一下django的文档,
在这里插入图片描述
在这里,实际上的意思就是,评论这两个功能的代码是写到评论保存的这个位置,也就是说,当我们评论保存的时候,就说明用户是评论了,那么评论保存这个操作发生,就会执行这两个操作。可能我们的评论保存有很多个地方执行,只要一保存就执行发送站内通知和发送邮件通知这两个操作,那我们能不能有种机制,当评论保存的时候,我们监听到这个消息,我们接收到评论保存的这个信号后,去执行这两个操作,而这两个操作的代码我们不在这里写。这大概就是signal所要实现的东西,它可以把我们的代码抽离出来,这样的话,维护起来也很方便。

那这里我们要怎么去实现呢,我们需要做的是,去监听一下有没有这个发生评论保存的行为。
打开mysite/comment,新建signals.py,写入如下代码:

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\comment\signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.html import strip_tags
from notifications.signals import notify
from .models import Comment


# 用来发送站内消息
@receiver(post_save, sender=Comment) # 信号接收器,指定由Comment这个模型发送出来,
def send_notification(sender, instance, **kwargs): # 参数:发送者、具体实例(这里对应的是comment)、额外参数
	# 发送站内消息
	if instance.reply_to is None: # 如果reply_to是None的话,那么就是评论,否则就是评论
		# 评论
		# 如果是评论的话,需要找到评论的主体(我们这里是博客)
		recipient = instance.content_object.get_user()
		if instance.content_type.model == 'blog':
			blog = instance.content_object
			verb = '{0} 评论了你的 《{1}》'.format(instance.user.get_nickname_or_username(), blog.title)
		else:
			raise Exception('unknow comment object type')
	else:
		# 回复
		recipient = instance.reply_to
		verb = '{0} 回复了你的评论“{1}”'.format(
				instance.user.get_nickname_or_username(), 
				strip_tags(instance.parent.text)
			)

	notify.send(instance.user, recipient=recipient, verb=verb, action_object=instance) 

接着我们要怎么去注册下这个信号接收器,让django知道呢。这个信号接收器有一个特点,它只能运行一次(如果运行多次会有问题),这里我们打开comment/apps.py,里面是comment这个app的配置,这里我们加多一个ready方法,这个方法是AppConfig里面自带的,super继承它,然后下面我们就可以写自己的代码,import 引入当前文件下的signals文件
在这里插入图片描述
而我们这个AppConfig还没使用,我们需要在comment/_init.py这个文件中去把它加进去,写入如下代码,default_app_config指定app去用哪个配置:
在这里插入图片描述

接着我们重启本地服务,刷新页面,随机评论一篇博客,可以看到,消息发送成功,这样的话,我们就成功把代码从views.py中抽离出来
在这里插入图片描述
在这里插入图片描述

同样的,发送邮件通知这部分,我们也可以抽离出来写到消息接收器里,在signals.py中加多一个消息接收器
在这里插入图片描述
在这里插入图片描述

这里我们还可以做进一步的代码分离,comment里面发送邮件是在models.py里,而model里面一般是写模型而不是写方法,所以发送邮件的方法不应该写在这里面,我们可以抽离出来,写到signals.py中
在这里插入图片描述
在这里插入图片描述
然后重启本地服务,测试如下,发现是成功的。这样,我们就通过signal这个信号机制,把代码从model和views里面抽离出来了,这样的话,代码就很清晰,便于维护
在这里插入图片描述
在这里插入图片描述

我们刚刚用到是一个信号,就是接收我们这个对象,当它发生保存这个操作的时候,我们接收到这个信号之后去执行一些操作,它是不用管什么地方是干什么的,也不用管前面后面执行什么,它只管接收到这个信号,而这个信号是django里面内置的信号,除了刚刚的那个保存信号之外,还有其他的内置信号。

另外signals文件怎么去使用。我们在app目录下创建这个文件后,写好这些信号接收器,接着在apps.py中ready引用进去,然后在init.py里面去使用AppConfig这个配置,就可以。

当然,信号接收器除了使用它内置的东西之外,我们还可以去自定义

至此,我们实现了评论/回复发送消息通知被评论人这个功能,同样的,点赞发送消息通知被点赞的人这个功能也可以去实现,我们同样采用signal这种方法。

我们需要监听LikeRecord这个模型,在mysite/likes目录下新建signals.py,写入如下代码:

  • 对于recipient参数:
    这里我们需要判断点赞的对象是博客还是评论
    如果是博客,对应的content_object就是blog,那么接收者就可以直接用blog-models对应的这个get_user()就能得到
    如果是评论,对应的content_object就是comment,在comment-models里面可以看到用户是user,这里我们也同样可以跟blog-models里面一样保持一致,定义一个get_user(),修改comment/models.py如下:
    在这里插入图片描述

  • 对于verb参数:
    消息内容,如果是点赞博客,消息内容为“某某某点赞了你的某篇博客”;如果是点赞评论,消息内容为“某某某点赞了你的评论”,所以这里我们还是要区分情况去写的

mysite\likes\signals.py:

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\likes\signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.html import strip_tags
from notifications.signals import notify
from .models import LikeRecord


# 用来发送站内消息
@receiver(post_save, sender=LikeRecord) # 信号接收器,指定由LikeRecord这个模型发送出来,
def send_notification(sender, instance, **kwargs): # 参数:发送者、具体实例(这里对应的是LikeRecord)、额外参数
	
	recipient = instance.content_object.get_user()

	if instance.content_type.model == 'blog':
		blog = instance.content_object
		verb = '{0} 点赞了你的 《{1}》'.format(instance.user.get_nickname_or_username(), blog.title)
	elif instance.content_type.model == 'comment':
		comment = instance.content_object
		verb = '{0} 点赞了你的评论“{1}”'.format(
				instance.user.get_nickname_or_username(), 
				strip_tags(comment.text)
			)

	notify.send(instance.user, recipient=recipient, verb=verb, action_object=instance) 

这样,点赞的接收消息通知的接收器就写好了,接着我们同样再完善一下apps.py和init.py
在这里插入图片描述
在这里插入图片描述

刷新页面,测试一下,我们分别给某篇博客和某个评论点赞,
在这里插入图片描述
在这里插入图片描述

接着我们再实现第三个功能:用户注册发送消息。当用户注册成功之后,发送一条消息
在user目录下新建signals.py,写入如下代码:

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\user\signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from notifications.signals import notify


# 用来发送站内消息
@receiver(post_save, sender=User) 
def send_notification(sender, instance, **kwargs): 
	if kwargs['created'] == True:	# 用这个参数来判断是不是第一次创建的用户
		verb = '注册成功,更多精彩内容等你发现'
		notify.send(instance, recipient=instance, verb=verb, action_object=instance)

复制一个apps.py文件到user目录下,修改如下:
在这里插入图片描述
init.py同理
在这里插入图片描述

保存之后,我们刷新页面,重新注册一个用户(为了方便,这里可以直接登录管理员账号,然后去后台管理中创建一个用户)
在这里插入图片描述
然后登陆这个用户,点开“我的消息”,可以看到有这条消息
在这里插入图片描述

44、站内消息通知(Part2)

要区分消息是已读还是未读,这有很多种方式都可以,比如直接简单的写出来是已读还是未读,也可以写两个页面:已读和未读页面,这实现起来也不难,直接将my_notifications.html里面的notifications.all改为.read.unread就可以。

这里我们打算把所有消息都罗列到这里,未读是一种样式,已读是一种样式,
我们在my_notifications.html里加一个a标签链接,这就可以作为未读消息显示的样式,而已读消息可以让整条消息显示成灰色。这样的话,我们就不需要对未读消息做一些样式的改变,只需要对已读消息做样式的改变,这里加一条判断,修改my_notifications.html如下:
在这里插入图片描述

在mysite/static目录下创建my_notifications.css,写入如下代码:
在这里插入图片描述

.read {
	color: #bbb;
}

.read a{
	color: #bbb;
}

然后我们进入到后台管理页面,将某条消息设为已读,然后刷新消息页面,可以看到已读和未读消息的颜色样式,这样子就可以很快的区分已读和未读
在这里插入图片描述
在这里插入图片描述

我们刚刚加的那个链接a标签,是要跳转到具体的页面,那这个具体页面的链接,我们也有好几个方式去实现
首先我们现在在这个位置,也读到了这条消息,那是否可以通过这条消息所发生消息的对象去找到具体页面呢,比如评论,触发消息的对象是评论这条消息,点赞也是点赞所触发的,那我们可以通过评论或者点赞得到具体的链接。
但是如果是在这个页面临时去读这个链接的话,不是特别好,如果这里有很多条消息,它每个都要运行一遍,每次我们打开“我的消息”这个页面都要等一段时间去得到这些链接。最好就是,我们在发送这条消息的时候,把这个链接保存进来,那么就读取notification某个属性得到这个链接。那么这里就要两个地方需要操作:(1)生成这个链接、(2)把链接保存到notification以便我们后面直接从notification这条消息读出这个链接

打开comment-signals.py:
(1)获取url:url = instance.content_object.get_url()
(2)notify发送消息,我们url参数最好是写到这里面去,我们可以查看下notification官方文档
在这里插入图片描述
打开base.py,加入代码DJANGO_NOTIFICATIONS_CONFIG = {'USE_JSONFIELD':True}
在这里插入图片描述
然后修改signals.py如下:
在这里插入图片描述
接着,我们要怎么在这个页面呈现出来。修改my_notifications.html如下:
在这里插入图片描述
我们先在后台页面删除所有消息,然后刷新页面,对某篇博客评论,然后点开“我的消息”,点这个消息链接,就可以跳转到对应页面,评论就在相应的位置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

当然,它能直接定位到这个位置是最好的,这里也有一个方法可以处理,就是在浏览器链接上面加上一个#号,再加上我们要定位位置的id属性值,这个id属性值前面也有设置,我们按F12查看,可以看到这条评论的id属性值是comment_数字,这个数字是这条评论的主键值。我们可以修改下这个url链接,修改signals.py如下:
在这里插入图片描述

然后我们再评论一次,刷新页面,点开“我的消息”,点击这条评论的链接,就可以看到我们能直接跳转定位到这篇博客的评论区里该评论所在位置,并且url变成了#comment_数字
在这里插入图片描述
在这里插入图片描述

还有个细节问题,实际上有时候这个跳转不是特别准确,甚至有些浏览器不会自动的跳转到我们所要的这个元素的位置,这里我们可以在加载这个页面的时候,做一个动画滚动到这个位置。
首先我们需要写一些js代码,要先得到我们要定位元素的id属性值,id属性值是在url里面,这个我们可以通过window.location.hash得到,刚好有一个#号,#号在jquery代码里面是可以做一个选择器找到id属性值的,
打开具体博客页面mysite/blog/templates/blog/blog_detail.html,加一个滚动的效果。然后刷新页面,点击消息通知里面的某条消息,就可以看到对应页面的滚动效果了:
在这里插入图片描述

评论这部分我们写好了,然后就是点赞部分,也要加一下这个链接
这里likes/signals.py里面url获取需要通过两步,分别由blog和comment这两个主体去获取,这里我们可以在comment-models里面加多一个get_url()获取链接的方法(参考blog-models里面添加的get_url方法),这样的话,likes-signals.py里面,获取url就可以直接全都通过get_url来获取,
修改comment/models.py如下:
在这里插入图片描述
然后修改likes/signals.py如下:
在这里插入图片描述

第三个位置,就是注册后的消息通知
修改user/signals.py如下:
在这里插入图片描述

这里还有一个内容没有讲,刚刚我们评论那里url,我们有定位到具体那条评论,那我们点赞这里,需不需要定位到具体位置呢?实际上这里是不需要的,这里不再是通过技术层面去考虑,而是通过我们具体的使用情况。因为在消息页面,如果是点赞,这里很明显看得到是点赞了哪个内容,就不需要点进去链接定位到具体位置查看了;而如果是评论,很明显这里没有显示评论内容,我们需要点进去链接定位到具体位置 查看具体的评论内容

现在,我们三个地方对应的链接都写好了。我们现在要做的是,点击消息过后,将消息显示为已读(参考之前我们写的博客列表,点击某篇博客,跳转到该博客具体页面)
修改mysite/urls.py:
在这里插入图片描述
然后加对应的处理方法,修改mysite/views.py如下:
在这里插入图片描述

那现在,这里页面就不再是直接显示链接给我们去跳转,而是找到my_notification具体通知的链接。修改my_notifications.html如下:
在这里插入图片描述

刷新页面,可以看到通知的具体链接不再是具体博客对应的url了,而是通知对应的url,通知的链接有一个处理方法,将消息改为已读 然后再跳转到之前的链接页面(即,之前的url,就是单纯的点击消息后,跳转到对应页面,而消息的状态显示的还是未读,而我们修改后的url,是具体的通知消息链接,里面有一个将消息改为已读然后再跳转的处理方法),这样更符合我们的使用逻辑。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

现在我们接着完善消息页面
假如这个页面有很多条消息,我们可以加一个按钮,让它全部变成已读,再加一个按钮,可以删掉全部消息,
打开my_notifications.html,加上按钮:
在这里插入图片描述
这里稍微调整下css样式,修改my_notifications.css如下:.notifications {margin-top: 1em;}

回到my_notifications.html,那现在就是我们点一下“全部标记为已读”的按钮,所有未读的消息就会变成已读,这个功能不需要我们写,在django-notifications里面有写,在mysite_env/Lib/site-packages/notifications/views.py中的mark_all_as_read,将所有消息变成已读。我们可以用mysite/urls.py中notifications的命名空间加上:mark_all_as_read,就可以获取到这个url链接,然后next参数,对应处理完这个页面之后要跳转到哪个位置
在这里插入图片描述
在这里插入图片描述
刷新页面,点击“全部标记为已读”按钮,就能成功将所有未读消息变成已读
在这里插入图片描述
同样的,删除已读消息,我们要加多一条链接,可以看到django-notifications里没有删除已读消息这个方法,这就需要我们自己写这样一个处理方法,但是这个处理方法如果写到mysite/views.py中的话,我们会发现views.py中的关于notification的内容就会越来越多了,就会越来越复杂,这样的话,其实我们可以将notification的部分单独写成一个app,把与之相关的内容都放在一起,

在mysite目录下新建一个my_notifications文件夹,复制一个init.py文件进来,
首先是url,新建文件urls.py:把mysite/urls.py里面my_notifications相关的两条url剪切过来,修改如下:

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\my_notifications\urls.py
from django.urls import path
from . import views

urlpatterns = [
	path('', views.my_notifications, name='my_notifications'),
    path('<int:my_notification_pk>', views.my_notification, name='my_notification'),
]

接着是views,新建views.py,代码如下:

# # C:\Users\12482\Desktop\py_learn\Django2.0_chapter46\mysite_env\mysite\my_notifications\views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse
from notifications.models import Notification

def my_notifications(request):
	context = {}
	return render(request, 'my_notifications/my_notifications.html', context)

def my_notification(request, my_notification_pk):
	my_notification = get_object_or_404(Notification, pk=my_notification_pk) # 得到这条消息通知
	my_notification.unread = False	# 得到这个通知之后,将unread改为False
	my_notification.save() # 保存
	return redirect(my_notification.data['url'])	# 重定向,跳转到这条通知的具体url

另外,还有静态文件,在my_notifications目录下,新建文件夹static/my_notifications,然后将mysite/static/my_notifications.css剪切到这里。(这里我们还需要将my_notifications.html里面用到这个静态文件的路径修改一下)
在这里插入图片描述

在这里插入图片描述
最后我们还要在mysite/urls.py中引用一下,加入代码path('my_notifications',include('my_notifications.urls')),
在这里插入图片描述
然后我们在settings中将这个应用注册一下,在base.py中加多一行代码'my_notifications',
在这里插入图片描述
那现在我们在my_notifications/views.py中加多一个方法,删除已读消息
在这里插入图片描述
然后在urls.py中也要加上该方法的路由:
在这里插入图片描述
最后,在my_notifications.html里面删除已读消息按钮的位置,加上该url,然后在my_notifications下新建templates/my_notifications,把这个html文件剪切进去:
在这里插入图片描述

刷新页面,点击“删除已读消息”按钮,成功删除
在这里插入图片描述
在这里插入图片描述

现在我们做最后一个功能,当有消息的时候,我们在外面是看不到这个消息的,而是要自己点击“我的消息”页面才能查看得到。所以如果我们在外面看得到有未读消息就可以直接点进去,这里我们就需要加一个未读消息在导航栏这里。查看django-notifications-hq的官方文档:
在这里插入图片描述

修改templates/base.html如下:
在这里插入图片描述
刷新页面。我们任意评论一条,会发现导航栏这里会出现未读消息数量1,
在这里插入图片描述
但这个显示不是特别的清晰,我们还可以用Bootstrap提供的徽章
在这里插入图片描述
修改base.html如下
在这里插入图片描述
刷新
在这里插入图片描述
但这个颜色不太明显,我们接着来修改下,修改base.html如下,多个一个class标签:
在这里插入图片描述
然后修改对应的css如下:
在这里插入图片描述
刷新
在这里插入图片描述
接着我们想要在下拉菜单“我的消息”里面加一个
在这里插入图片描述
修改base.html如下:
在这里插入图片描述
刷新页面
在这里插入图片描述

然后我们点击未读消息之后,变成已读,那么未读消息数量就变成0,实际上0这个消息我们不应该把它给显示出来
修改base.html如下:
在这里插入图片描述

还有一个问题需要处理。我们点完赞之后,虽然不是给自己点的,对应的那个人可以看得到,但那个人不会直接的刷新,他这个页面可能会过一段时间才能看到这个消息,这里有个实时获取未读消息数量,这个功能实际上我们可以用ajax实现,不过这个第三方库也考虑到了这个问题,它也实现了实时获取

5、实时获取消息

  • django-notifications-hq提供了一套api可以实时获取
  • 加载notifications/notify.js
  • 使用register_notify_callback模板标签
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
修改base.html如下:
在这里插入图片描述
在这里插入图片描述

然后我们点赞几条评论,等待几秒钟,就会发现数量会变化。
在这里插入图片描述

这是通过ajax代码提交一个请求,获取到数量填入到这里,我们可以按F12查看下,可以看到它是有个class名称,它实际上是去获取class名称,然后把这个数量填进去,那这里我们可以不用它自己提供的标签,我们可以把这个class名称放到html里,修改base.html如下:
在这里插入图片描述
在这里插入图片描述

再刷新页面,再点个赞,等待几秒,会发现右上角数量加1,下拉“我的消息”也是加1
在这里插入图片描述

我们进去消息页面,将所有消息变成已读,我们会发现这里数量又会出现个0,因为重新读取,就会把0这个数据填入进去。
在这里插入图片描述

这里我们可以自定义一个方法进行处理
在这里插入图片描述
修改base.html如下:
在这里插入图片描述

刷新页面,我们随便点赞一条评论,等待未读消息数量的徽标出现,然后进入“我的消息”,点击“全部标记为已读”,等待几秒,可以看到右上角导航栏没有再显示0了
在这里插入图片描述
在这里插入图片描述

至此,所有的站内消息通知的功能我们全部实现了

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Django是一个使用Python编写的Web应用程序框架,它提供了许多强大的工具和功能来帮助开发人员快速构建高效的Web应用程序。 要玩转Django 2.0代码,首先需要安装Django 2.0,并且熟悉其基本的目录结构和文件组织方式。在创建一个新的Django项目时,可以使用命令行工具来生成基本的项目结构,然后在其中创建应用程序并定义模型、视图和模板。 在使用Django 2.0开发Web应用程序时,需要熟悉Django的MTV(模型-模板-视图)架构,这是Django应用程序的核心概念。模型用于定义数据结构和处理数据库操作,视图负责处理用户请求并返回响应,模板则用于生成最终的用户界面。 此外,了解如何使用Django 2.0的路由系统来处理URL映射和视图函数的调度也非常重要。可以使用Django的路由配置来定义URL模式,并将它们映射到相应的视图函数上。 另外,了解Django 2.0的表单处理、认证和权限管理功能也是必不可少的。Django提供了丰富的表单组件和验证工具,可以帮助开发人员快速构建复杂的表单。而用户认证和权限管理方面,Django提供了强大的认证和授权系统,可以帮助开发人员轻松实现用户注册、登录和权限控制。 总之,要玩转Django 2.0代码,需要深入了解Django的核心概念和功能,并且通过实际的项目实践来提升自己的编码技巧和经验。希望以上回答能帮助你更好的学习和应用Django 2.0。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值