关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
添加评论和回复功能限制了只能注册用户才能评论和回复。前面就加了用户认证功能,可参考博文:
有了用户之后,得给个页面查看相关信息和修改资料等。开发这东西是需要一步一步完善的,所以今天完善一下这个功能,添加用户中心。大概要做成如下页面:
分3个部分:用户信息,评论统计,评论列表。
那么先写这些获取这些数据,方便提交给模板。在根目录下的helper文件夹(我专门放置辅助脚本的文件夹)添加comments_count.py文件,代码如下:
#coding:utf-8 from django.db import connection, transaction import django_comments from blog.models import Blog def get_comments_count(user_id, content_type = 'blog'): """get the blog comments count""" #获得一个游标(cursor)对象 cursor = connection.cursor() sql = ur""" select count(django_comments.id) from django_comments left join django_content_type on django_comments.content_type_id = django_content_type.id where django_content_type.app_label = %s and user_id = %s and root_id = 0 """ paras = [content_type, user_id] cursor.execute(sql, paras) #执行sql语句 raw = cursor.fetchone() #获取第一行 return raw[0] def get_replies_count(user_id, content_type = 'blog'): """get the blog replies count""" #获得一个游标(cursor)对象 cursor = connection.cursor() sql = ur""" select count(django_comments.id) from django_comments left join django_content_type on django_comments.content_type_id = django_content_type.id where django_content_type.app_label = %s and user_id = %s and root_id > 0 """ paras = [content_type, user_id] cursor.execute(sql, paras) #执行sql语句 raw = cursor.fetchone() #获取第一行 return raw[0] def get_to_reply_count(user_id, content_type = 'blog'): """get to be replyed count""" #获得一个游标(cursor)对象 cursor = connection.cursor() sql = ur""" select count(django_comments.id) from django_comments where user_id = %s and id in ( select django_comments.reply_to from django_comments left join django_content_type on django_comments.content_type_id = django_content_type.id where django_content_type.app_label = %s and root_id>0) """ paras = [user_id, content_type] cursor.execute(sql, paras) #执行sql语句 raw = cursor.fetchone() #获取第一行 return raw[0] def last_talk_about(user_id, content_type = 'blog'): """get last talk about blog""" #获得一个游标(cursor)对象 cursor = connection.cursor() sql = ur""" select django_comments.object_pk from django_comments left join django_content_type on django_comments.content_type_id = django_content_type.id where django_content_type.app_label = %s and user_id=%s order by submit_date desc limit 1 """ paras = [content_type, user_id] cursor.execute(sql, paras) #执行sql语句 raw = cursor.fetchone() #获取第一行 try: return Blog.objects.get(id = raw[0]) except Exception as e: return None def all_talk_about(user_id): """get all talk about blogs""" sql = ur""" select blog_blog.* from blog_blog where id in (select django_comments.object_pk from django_comments left join django_content_type on django_comments.content_type_id = django_content_type.id where django_content_type.app_label = 'blog' and user_id=%s) """ % user_id blogs=list(Blog.objects.raw(sql)) #raw_query对象是一个生成器 comment_model = django_comments.get_model() for blog in blogs: sql = ur""" select django_comments.* from django_comments left join django_content_type on django_comments.content_type_id = django_content_type.id where django_content_type.app_label = 'blog' and user_id=%s and django_comments.object_pk='%s' order by submit_date desc """ % (user_id, blog.id) blog.comments = comment_model.objects.raw(sql) return blogs
分别用sql语句获取评论和回复的统计数量。
get_comments_count方法,获取指定用户的评论数;
get_replies_count方法,获取指定用户回复其他人的数量;
get_to_reply_count方法,获取指定用户被回复的次数;
last_talk_about方法,获取最后一个参与评论或回复的博文;
all_talk_about方法,获取所有评论和回复。
这里需要稍微说明一下的是all_talk_about方法。用模型对象的raw方法获取相关对象。但它是一个生成器,为了方便关联相关的评论和回复,我就先将其转行成list,再动态添加一个comments属性用于存放相关的评论和回复。
再修改一下,user_ex的拓展方法views.py文件,加上如下代码:
from helper import comments_count #添加用户中心的响应方法 def user_info(request): '''show the user infomations''' data={} user = request.user #判断是否登录了 if request.user.is_authenticated(): data['user'] = user data['comments_count'] = comments_count.get_comments_count(user.id) data['replies_count'] = comments_count.get_replies_count(user.id) data['replyed_count'] = comments_count.get_to_reply_count(user.id) data['last_talk_about'] = comments_count.last_talk_about(user.id) data['all_talk_about'] = comments_count.all_talk_about(user.id) return render_to_response('user/index.html',data) else: data['message'] = u'您尚未登录,请先登录' #提示消息 data['goto_page'] = True #是否跳转 data['goto_url'] = '/' #跳转页面 data['goto_time'] = 3000 #等待多久才跳转 return render_to_response('message.html',data) #修改检查是否登录的代码 def check_is_login(request): """check the user is logined""" if request.user.is_authenticated(): #change 2016-5-20 username = request.user.first_name or request.user.username active_state = '' if request.user.is_active else u'(未激活)' admin_url = u'<li><a href="%s">后台管理</a></li>' % reverse('admin:index') if request.user.is_superuser else '' returnText=u''' <li role="presentation" class="dropdown"> <a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false"> 您好,%s%s <span class="caret"></span> </a> <ul class="dropdown-menu"> <li><a href="%s">用户中心</a></li> %s <!--<li role="separator" class="divider"></li>--> <li><a href="%s">退出</a></li> </ul> </li>''' % (username, active_state, reverse('user_info'), admin_url, reverse('user_logout')) else: returnText=u""" <li><a href="#" data-toggle="modal" data-target="#LoginModal">登录</a></li> <li><a href="#" data-toggle="modal" data-target="#RegModal">注册</a></li>""" return HttpResponse(returnText, content_type='application/javascript')
加了处理响应的方法,别忘了加上url的设置。
url(r'^user_info$','user_ex.views.user_info',name='user_info'),
这里用到了两个模版,一个是正常的用户中心模版,一个是没有登录用到的消息提醒模版。
用户中心模版:
{% extends "base.html" %} {% block title %}用户中心 - 杨仕航的博客{% endblock %} {% block blog_active %}active{% endblock %} {% block content %} <div class="row"> <div class="col-md-5"> <div class="panel panel-default"> <div class="panel-heading">我的信息</div> <div class="panel-body"> <div class=""> <h4 class="user-name">{% if user.first_name %}{{user.first_name}}{%else%}{{user.username}}{%endif%}</h4> <span><a href="#">修改昵称</a></span> <span><a href="#">修改密码</a></span> </div> <ul class="user-info"> <li> <span>注册邮箱:</span> <span>{{user.username}}</span> </li> <li> <span>注册日期:</span> <span>{{user.date_joined|date:"Y-m-d H:i"}}</span> </li> <li> <span>最近登录:</span> <span>{{user.last_login|date:"Y-m-d H:i"}}</span> </li> </ul> </div> </div> </div> <div class="col-md-7"> <div class="panel panel-default"> <div class="panel-heading">我的足迹</div> <div class="panel-body"> <div class=""> <h4 class="user-name">信息统计</h4> <span>最近参与讨论的文章: {% if last_talk_about %} <a href="/blog/{{last_talk_about.id}}" target="_blank">{{last_talk_about.caption}}</a> {% else %} 无 {% endif %} </span> </div> <ul class="user-info"> <li>您共评论了<b>{{comments_count}}</b>次</li> <li>您共回复了<b>{{replies_count}}</b>次</li> <li>有<b>{{replyed_count}}</b>次,其他人回复了您</li> </ul> </div> </div> </div> <div class="col-md-12"> <div class="panel panel-default"> <div class="panel-heading">我的发言</div> <div class="panel-body"> {% for blog in all_talk_about %} <div class="sp-item"> <h5 class="sp-title"><a href="/blog/{{blog.id}}" target="_blank">{{blog.caption}}</a></h5> <ul class="sp-detail"> {% for comment in blog.comments %} <li>{{comment.submit_date|date:"Y-m-d H:i"}} {% if comment.root_id %}回复 <span class="label label-primary">{{comment.reply_name}}</span>{%else%}评论{%endif%}: {{comment.comment}}</li> {% endfor %} </ul> </div> {% endfor %} <p class="text-right">查看更多博文发表您的宝贵意见吧~ <a href="/blog/" target="_blank">看博客>></a></p> </div> </div> </div> </div> </div> <style type="text/css"> .user-info{ margin-top: 1em; } .sp-item{ margin-bottom: 2em; border-bottom: 1px #ccc dashed; } .sp-item li{ text-indent: 1em; padding-bottom: 0.3em; } </style> {% endblock %}
消息提醒模版:
{% extends "base.html" %} {% block title %}杨仕航的博客{% endblock %} {% block content %} {#显示消息的页面#} <div class="row"> <center><h4 style="line-height:300%;">{{message|safe}}</h4></center> </div> {% endblock %} {% block extra_footer %} <script type="text/javascript"> {#页面调整控制#} {% if goto_page %} $(function(){ window.setTimeout(function(){ window.location = '{{goto_url}}'; },{{goto_time}}); }); {% endif %} </script> {% endblock %}
这样,登录之后,可以在用户名的下拉列表进入用户中心。接下来要添加修改昵称和修改密码功能。