Django+Nginx+uwsgi搭建自己的博客(八)

在这篇博客中,我们开始为我们的博客开发Blogs App和Users App相关的管理功能,以便每个用户都能管理自己的博客以及评论。目前,Users App的管理功能相对简单,主要功能为查看用户资料以及切换到博客管理页面,如下所示:

在点击了博客管理后,页面将跳转到管理页面,在此可进行对博客的各种管理:

我们的博客管理操作支持对博客的编辑、删除,对草稿的编辑、删除和对评论的删除操作,以及还没有开发的类别管理功能。

首先来添加用户管理功能。我们需要开发一个新页面userIndex来作为用户管理的主页,在该页上会显示出该用户所有的博客列表,以及提供查看用户资料和博客管理的入口。为此,我们需要添加在Users App的目录中添加userTemplate.html作为用户管理的模板,代码如下:

  1. <!-- userTemplate.html -->  
  2. <!DOCTYPE html>  
  3. <html lang="zh">  
  4. <head>  
  5.     <meta charset="UTF-8">  
  6.     <script type="text/javascript" src="/static/ckeditor/ckeditor-init.js" data-ckeditor-basepath="/static/ckeditor/ckeditor/" id="ckeditor-init-script"></script>  
  7.     <script type="text/javascript" src="/static/ckeditor/ckeditor/ckeditor.js"></script>  
  8.     <script type="text/javascript" src="/static/js/jquery-3.2.1.min.js"></script>  
  9.     <title>Cap_Liu的博客</title>  
  10. </head>  
  11. <style type="text/css">  
  12.     <!-- CSS部分略 -->     
  13. </style>  
  14. <body>  
  15. <h1>Cap_Liu的博客</h1>  
  16. <div class="introduce">  
  17. {{ test }}  
  18. </div>  
  19. <div class="nav">  
  20. {% if username == currentUser.username and currentUser.username != "anony" %}  
  21. <span><a href="{% url 'index' %}">首页</a></span>  
  22. <span><a href="{% url 'users:userinfo' username %}">用户资料</a></span>  
  23. <span><a href="{% url 'blogs:blogmanage' %}">博客管理</a></span>  
  24. {% else %}  
  25. <span><a href="{% url 'index' %}">首页</a>  
  26. <span><a href="{% url 'users:userinfo' username %}">用户资料</a></span>  
  27. {% endif %}  
  28. </div>  
  29. <div class="content">  
  30. {% block content %}  
  31. {% endblock %}  
  32. </div>  
  33. </body>  
  34. </html>  
<!-- userTemplate.html -->
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="/static/ckeditor/ckeditor-init.js" data-ckeditor-basepath="/static/ckeditor/ckeditor/" id="ckeditor-init-script"></script>
    <script type="text/javascript" src="/static/ckeditor/ckeditor/ckeditor.js"></script>
    <script type="text/javascript" src="/static/js/jquery-3.2.1.min.js"></script>
    <title>Cap_Liu的博客</title>
</head>
<style type="text/css">
    <!-- CSS部分略 -->	
</style>
<body>
<h1>Cap_Liu的博客</h1>
<div class="introduce">
{{ test }}
</div>
<div class="nav">
{% if username == currentUser.username and currentUser.username != "anony" %}
<span><a href="{% url 'index' %}">首页</a></span>
<span><a href="{% url 'users:userinfo' username %}">用户资料</a></span>
<span><a href="{% url 'blogs:blogmanage' %}">博客管理</a></span>
{% else %}
<span><a href="{% url 'index' %}">首页</a>
<span><a href="{% url 'users:userinfo' username %}">用户资料</a></span>
{% endif %}
</div>
<div class="content">
{% block content %}
{% endblock %}
</div>
</body>
</html>
在这里,要根据用户登录的用户名来判断是否要显示出博客管理的入口。若查看的用户资料与当前登录用户不符,则无法看到博客管理的入口。

然后,我们建立userindex.html作为用户管理的首页,即显示出该用户所有的博客:

  1. <!-- userindex.html -->  
  2. {% extends "userTemplate.html" %}  
  3. {% block content %}  
  4. <div id="content" class="list">  
  5. {% if blogList %}  
  6.     <ul>  
  7.     {% for blog in blogList %}  
  8.         <div class="articlelist">  
  9.         <a href="{% url 'blogs:content' blog.id %}">{{ blog.title }}</a>-<a href="{% url 'users:userIndex' blog.auther.username %}">{{ blog.auther }}</a>  
  10.         <div class="articlelistinfo">  
  11.         <span title="阅读次数">阅读 {{ blog.readcount }}</span>  
  12.         <span title="创建时间">{{ blog.createdate|date:"Y-m-d H:i:s" }}</span>  
  13.         </div>  
  14.         </div>  
  15.     {% endfor %}  
  16.     </ul>  
  17. {% else %}  
  18.     <p>No blogs</p>  
  19. {% endif %}  
  20. </div>  
  21. {% endblock %}  
<!-- userindex.html -->
{% extends "userTemplate.html" %}
{% block content %}
<div id="content" class="list">
{% if blogList %}
	<ul>
	{% for blog in blogList %}
		<div class="articlelist">
		<a href="{% url 'blogs:content' blog.id %}">{{ blog.title }}</a>-<a href="{% url 'users:userIndex' blog.auther.username %}">{{ blog.auther }}</a>
		<div class="articlelistinfo">
		<span title="阅读次数">阅读 {{ blog.readcount }}</span>
		<span title="创建时间">{{ blog.createdate|date:"Y-m-d H:i:s" }}</span>
		</div>
		</div>
	{% endfor %}
	</ul>
{% else %}
	<p>No blogs</p>
{% endif %}
</div>
{% endblock %}

userIndex的views函数如下:
  1. # users/views.py  
  2. # ...  
  3. def userIndex(request,username):  
  4.     try:  
  5.         user = Users.objects.get(username=username)  
  6.         currentUser = Users.objects.get(username=request.session['username'])  
  7.         blogList = Blog.objects.filter(auther=username).filter(draft=False)  
  8.         content = {'username':username,  
  9.                    'currentUser':currentUser,  
  10.                    'blogList':blogList  
  11.                    }  
  12.     except Exception as e:  
  13.         content = {'username':e}  
  14.     return render(request,'users/userindex.html',content)  
  15. # ...  
# users/views.py
# ...
def userIndex(request,username):
    try:
        user = Users.objects.get(username=username)
        currentUser = Users.objects.get(username=request.session['username'])
        blogList = Blog.objects.filter(auther=username).filter(draft=False)
        content = {'username':username,
                   'currentUser':currentUser,
                   'blogList':blogList
                   }
    except Exception as e:
        content = {'username':e}
    return render(request,'users/userindex.html',content)
# ...
以及,由于现在我们可以允许其他用户访问用户资料,因此我们要对这个系列第二篇中开发的userInfo函数进行修改,使之能根据不同的用户名显示不同用户的信息:
  1. # users/views.py  
  2. # ...  
  3. def userinfo(request,username):  
  4.     try:  
  5.         user = Users.objects.get(username=username)  
  6.         currentUser = Users.objects.get(username=request.session['username'])  
  7.         birthday = user.birthday  
  8.         email = user.email  
  9.         registertime = user.registertime  
  10.         content = {'username':username,  
  11.                    'registertime':registertime,  
  12.                    'birthday':birthday,  
  13.                    'email':email,  
  14.                    'currentUser':currentUser  
  15.                    }  
  16.     except Exception as e:  
  17.         pass  
  18.     return render(request,'users/userinfo.html',content)  
  19. # ...  
# users/views.py
# ...
def userinfo(request,username):
    try:
        user = Users.objects.get(username=username)
        currentUser = Users.objects.get(username=request.session['username'])
        birthday = user.birthday
        email = user.email
        registertime = user.registertime
        content = {'username':username,
                   'registertime':registertime,
                   'birthday':birthday,
                   'email':email,
                   'currentUser':currentUser
                   }
    except Exception as e:
        pass
    return render(request,'users/userinfo.html',content)
# ...
同时,我们也要对userInfo的url做对应的修改,以及添加userindex的url:
  1. # users/urls.py  
  2. # ...  
  3. urlpatterns = [  
  4. # ...  
  5.     url(r'^userindex/(?P<username>.*)$',views.userIndex,name='userIndex'),  
  6.     url(r'^userinfo/(?P<username>.*)$',views.userinfo,name='userinfo')  
  7. ]  
# users/urls.py
# ...
urlpatterns = [
# ...
    url(r'^userindex/(?P<username>.*)$',views.userIndex,name='userIndex'),
    url(r'^userinfo/(?P<username>.*)$',views.userinfo,name='userinfo')
]

这样,我们的Users App的管理功能就开发完毕了。现在的Users App的管理功能比较简单,并没有提供修改资料的功能,更主要的是为博客管理功能提供一个入口。

因此,现在我们来看看博客管理功能的实现。当前的博客管理功能包括5个页面articleList.html, blogmanage.html, commentmanage.html, draftmanage.html和failedoperation.html,分别对应文章列表、博客管理、评论管理、草稿箱和拒绝访问功能。为了保持页面风格的统一,以上页面都会继承blogManageTemplate.html模板,如下所示:

  1. <!-- blogManageTemplate.html-->  
  2. <!DOCTYPE html>  
  3. <html lang="zh">  
  4. <head>  
  5.     <meta charset="UTF-8">  
  6.     <script type="text/javascript" src="/static/ckeditor/ckeditor-init.js" data-ckeditor-basepath="/static/ckeditor/ckeditor/" id="ckeditor-init-script"></script>  
  7.     <script type="text/javascript" src="/static/ckeditor/ckeditor/ckeditor.js"></script>  
  8.     <script type="text/javascript" src="/static/js/jquery-3.2.1.min.js"></script>  
  9.     <title>Cap_Liu的博客</title>  
  10. </head>  
  11. <style type="text/css">  
  12.  <!--CSS部分略,与其他模板相同-->  
  13. </style>  
  14. <body>  
  15. <h1>Cap_Liu的博客</h1>  
  16. <div class="introduce">  
  17. {{ test }}  
  18. </div>  
  19. <div class="nav">  
  20. <span><a href="{% url 'index' %}">首页</a></span>  
  21. <span><a href="{% url 'blogs:articlelist' %}">文章列表</a></span>  
  22. <span><a href="{% url 'blogs:blogmanage' %}">博客管理</a></span>  
  23. <span><a href="{% url 'blogs:commentmanage' %}">评论管理</a></span>  
  24. <span>类别管理</span>  
  25. <span><a href="{% url 'blogs:draftmanage' %}">草稿箱</a></span>  
  26. </div>  
  27. <div class="content">  
  28. {% block content %}  
  29. {% endblock %}  
  30. </div>  
  31. <div class="content">  
  32. {% block comment %}  
  33. {% endblock %}  
  34. </div>  
  35. </body>  
  36. </html>  
<!-- blogManageTemplate.html-->
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
	<script type="text/javascript" src="/static/ckeditor/ckeditor-init.js" data-ckeditor-basepath="/static/ckeditor/ckeditor/" id="ckeditor-init-script"></script>
    <script type="text/javascript" src="/static/ckeditor/ckeditor/ckeditor.js"></script>
    <script type="text/javascript" src="/static/js/jquery-3.2.1.min.js"></script>
    <title>Cap_Liu的博客</title>
</head>
<style type="text/css">
 <!--CSS部分略,与其他模板相同-->
</style>
<body>
<h1>Cap_Liu的博客</h1>
<div class="introduce">
{{ test }}
</div>
<div class="nav">
<span><a href="{% url 'index' %}">首页</a></span>
<span><a href="{% url 'blogs:articlelist' %}">文章列表</a></span>
<span><a href="{% url 'blogs:blogmanage' %}">博客管理</a></span>
<span><a href="{% url 'blogs:commentmanage' %}">评论管理</a></span>
<span>类别管理</span>
<span><a href="{% url 'blogs:draftmanage' %}">草稿箱</a></span>
</div>
<div class="content">
{% block content %}
{% endblock %}
</div>
<div class="content">
{% block comment %}
{% endblock %}
</div>
</body>
</html>

下面来看看5个分页面的实现。blogmanage.html用于列出该用户所有的博客,并提供编辑和删除的功能:
  1. <!-- blogmanage.html -->  
  2. {% extends "blogManageTemplate.html" %}  
  3. {% block content %}  
  4. <div id="content" class="list">  
  5. <table>  
  6. <tr>  
  7. <td>标题</td>  
  8. <td>            </td>  
  9. <td>阅读数</td>  
  10. <td>    </td>  
  11. <td>评论数</td>  
  12. <td>    </td>  
  13. <td>操作</td>  
  14. </tr>  
  15. {% if blogList %}  
  16.     {% for blog in blogList %}  
  17.         <tr>  
  18.         <td><a href="{% url 'blogs:content' blog.id %}">{{ blog.title }}</a> ({{ blog.createdate|date:"Y-m-d H:i:s" }})</td>  
  19.         <td>            </td>  
  20.         <td>{{ blog.readcount }}</td>  
  21.         <td>    </td>  
  22.         <td>{{ blog.commentcount }}</td>  
  23.         <td>    </td>  
  24.         <td><span><a href="{% url 'blogs:editBlog' blog.id %}">编辑</a></span>|<span><a href="javascript:void(0);" onClick="deleteConfirm('{{ blog.title }}','{{ blog.id }}')">删除</a></span>  
  25.         </tr>  
  26.     {% endfor %}  
  27. {% else %}  
  28.     <p>No blogs</p>  
  29. {% endif %}  
  30. </table>  
  31. </div>  
  32. <script>  
  33. function deleteConfirm(title,id)  
  34. {  
  35.     var blogId = id;  
  36.     var url_mask = "{% url 'blogs:deleteBlog' 'tmpId' %}".replace('tmpId',blogId);  
  37.     if(confirm("确认删除" + title + "吗?"))  
  38.     {  
  39.         location.href = url_mask;  
  40.     }  
  41. }  
  42. </script>  
  43. {% endblock %}  
<!-- blogmanage.html -->
{% extends "blogManageTemplate.html" %}
{% block content %}
<div id="content" class="list">
<table>
<tr>
<td>标题</td>
<td>            </td>
<td>阅读数</td>
<td>    </td>
<td>评论数</td>
<td>    </td>
<td>操作</td>
</tr>
{% if blogList %}
	{% for blog in blogList %}
        <tr>
        <td><a href="{% url 'blogs:content' blog.id %}">{{ blog.title }}</a> ({{ blog.createdate|date:"Y-m-d H:i:s" }})</td>
        <td>            </td>
        <td>{{ blog.readcount }}</td>
        <td>    </td>
        <td>{{ blog.commentcount }}</td>
        <td>    </td>
        <td><span><a href="{% url 'blogs:editBlog' blog.id %}">编辑</a></span>|<span><a href="javascript:void(0);" onClick="deleteConfirm('{{ blog.title }}','{{ blog.id }}')">删除</a></span>
        </tr>
	{% endfor %}
{% else %}
	<p>No blogs</p>
{% endif %}
</table>
</div>
<script>
function deleteConfirm(title,id)
{
    var blogId = id;
    var url_mask = "{% url 'blogs:deleteBlog' 'tmpId' %}".replace('tmpId',blogId);
    if(confirm("确认删除" + title + "吗?"))
    {
        location.href = url_mask;
    }
}
</script>
{% endblock %}
在该页面中,会显示出博客的标题、阅读数和评论数,以及提供了编辑和删除的入口链接。这里值得注意的是,对于删除操作,我们需要使用javascript提供一个confirm对话框,防止用户的误操作。而在javascript中,{% url %}标记的参数不能直接设为javascript的变量,因此我们需要设置一个tmpId的占位符,在得到完整的url形式后再用replace函数把tmpId替换成真正的blogId,从而实现删除操作;而对于编辑操作,我们需要将欲编辑的文章的标题、类别和内容填入到addBlog页面中的各个表单中,因此需要修改在第七篇博客中的addBlog.html页面,使得表单的数据可以用后端数据直接填写:
  1. <!-- addBlog.html -->  
  2. <!--在javascript部分添加以下代码-->  
  3. <script>  
  4. $(document).ready(function(){  
  5.     $("#id_title").val('{{ title }}');  
  6.     $("#id_category").val('{{ category }}');  
  7.     $("#id_content").val('{{ content|safe }}');  
  8. });  
  9. </script>  
<!-- addBlog.html -->
<!--在javascript部分添加以下代码-->
<script>
$(document).ready(function(){
    $("#id_title").val('{{ title }}');
    $("#id_category").val('{{ category }}');
    $("#id_content").val('{{ content|safe }}');
});
</script>
下面来看一下blogmanage、editblog和deleteblog的view函数:
  1. # blogs/views.py  
  2. # ...  
  3. def blogmanage(request):  
  4.     if request.session['username'] == 'anony':  
  5.         return render(request, 'blogs/failedoperation.html')  
  6.     else:  
  7.         blogList = Blog.objects.filter(auther=request.session['username'])  
  8.     return render(request, 'blogs/blogmanage.html', {'blogList': blogList})  
  9.   
  10.   
  11. def deleteblog(request,blogId):  
  12.     blog = Blog.objects.get(id=blogId)  
  13.     if blog.auther.username == request.session['username']:  
  14.         blog.delete()  
  15.         blogList = Blog.objects.filter(auther=request.session['username'])  
  16.     else:  
  17.         return render(request, 'blogs/failedoperation.html')  
  18.     return HttpResponseRedirect(reverse('blogs:blogmanage'))  
  19.   
  20.   
  21. def editblog(request,blogId):  
  22.     tmpBlog = Blog.objects.get(id=blogId)  
  23.     request.session['currentblogId'] = blogId  
  24.     form = BlogForm()  
  25.     blogContent = {}  
  26.     if tmpBlog.auther.username == request.session['username']:  
  27.         blogContent = {  
  28.             'title':tmpBlog.title,  
  29.             'category':tmpBlog.category,  
  30.             'content':tmpBlog.content,  
  31.             'form':form  
  32.         }  
  33.     else:  
  34.         return render(request, 'blogs/failedoperation.html')  
  35.     return render(request, 'blogs/addblog.html', blogContent)  
  36. # ...  
# blogs/views.py
# ...
def blogmanage(request):
    if request.session['username'] == 'anony':
        return render(request, 'blogs/failedoperation.html')
    else:
        blogList = Blog.objects.filter(auther=request.session['username'])
    return render(request, 'blogs/blogmanage.html', {'blogList': blogList})


def deleteblog(request,blogId):
    blog = Blog.objects.get(id=blogId)
    if blog.auther.username == request.session['username']:
        blog.delete()
        blogList = Blog.objects.filter(auther=request.session['username'])
    else:
        return render(request, 'blogs/failedoperation.html')
    return HttpResponseRedirect(reverse('blogs:blogmanage'))


def editblog(request,blogId):
    tmpBlog = Blog.objects.get(id=blogId)
    request.session['currentblogId'] = blogId
    form = BlogForm()
    blogContent = {}
    if tmpBlog.auther.username == request.session['username']:
        blogContent = {
            'title':tmpBlog.title,
            'category':tmpBlog.category,
            'content':tmpBlog.content,
            'form':form
        }
    else:
        return render(request, 'blogs/failedoperation.html')
    return render(request, 'blogs/addblog.html', blogContent)
# ...

对于编辑博客和删除博客这种写操作,我们需要在后端检查博客的作者与当前登录的用户是否相同。相同则进行具体操作,若不同则会跳转至failedoperation.html:
  1. <!-- failedoperation.html -->  
  2. {% extends "blogManageTemplate.html" %}  
  3. {% block content %}  
  4. <div id="content" class="list">  
  5. <h2>没有权限进行此操作</h2>  
  6. </div>  
  7. {% endblock %}  
<!-- failedoperation.html -->
{% extends "blogManageTemplate.html" %}
{% block content %}
<div id="content" class="list">
<h2>没有权限进行此操作</h2>
</div>
{% endblock %}

在后端检查用户的目的在于,即使前端无法看到编辑或删除的入口,也可以通过拼凑url的方式达到非法编辑或删除的目的。而对于blogManage页面,我们只需检查是否为匿名用户即可,因为该页面不会涉及任何具体操作,只是为编辑和删除操作提供入口。

对于editblog,我们可以复用addblog.html作为编辑的页面,并为其传入博客的标题、种类以及内容,以便通过javascript填入表单;同时,我们还需将currentblogId的值设为当前编辑的blogId,表示我们正在编辑该篇博客。

commentmanage.html用于显示该用户下所有博客的所有评论,包括评论内容、评论作者以及发表时间,博主可以对每条评论实施删除操作。页面代码如下:

  1. <!-- commentmanage.html -->  
  2. {% extends "blogManageTemplate.html" %}  
  3. {% block content %}  
  4. <div id="content" class="list">  
  5. <table>  
  6. <tr>  
  7. <td>标题</td>  
  8. <td>            </td>  
  9. <td>作者</td>  
  10. <td>    </td>  
  11. <td>时间</td>  
  12. <td>    </td>  
  13. <td>操作</td>  
  14. </tr>  
  15. {% if commentList %}  
  16.     {% for comment in commentList %}  
  17.             {% for realcomment in comment %}  
  18.                 <tr>  
  19.                 <td><a href="{% url 'blogs:content' blog.id %}">{{ realcomment.attachedblog.title }}</a>   ({{ realcomment.attachedblog.createdate|date:"Y-m-d H:i:s" }})<br>  
  20.                 {{ realcomment.content }}  
  21.                 </td>  
  22.                 <td>            </td>  
  23.                 <td>{{ realcomment.auther.username }}</td>  
  24.                 <td>    </td>  
  25.                 <td>{{ realcomment.createtime }}</td>  
  26.                 <td>    </td>  
  27.                 <td><span><a href="javascript:void(0);" onClick="deleteConfirm('{{ realcomment.id }}')">删除</a></span>  
  28.                 </tr>  
  29.             {% endfor %}  
  30.     {% endfor %}  
  31. {% else %}  
  32.     <p>No comments</p>  
  33. {% endif %}  
  34. </table>  
  35. </div>  
  36. <script>  
  37. function deleteConfirm(id)  
  38. {  
  39.     var commentid = id;  
  40.     var url_mask = "{% url 'blogs:deleteComment' 'tmpId' %}".replace('tmpId',commentid);  
  41.     if(confirm("确认删除该评论吗?"))  
  42.     {  
  43.         location.href = url_mask;  
  44.     }  
  45. }  
  46. </script>  
  47. {% endblock %}  
<!-- commentmanage.html -->
{% extends "blogManageTemplate.html" %}
{% block content %}
<div id="content" class="list">
<table>
<tr>
<td>标题</td>
<td>            </td>
<td>作者</td>
<td>    </td>
<td>时间</td>
<td>    </td>
<td>操作</td>
</tr>
{% if commentList %}
	{% for comment in commentList %}
            {% for realcomment in comment %}
                <tr>
                <td><a href="{% url 'blogs:content' blog.id %}">{{ realcomment.attachedblog.title }}</a>   ({{ realcomment.attachedblog.createdate|date:"Y-m-d H:i:s" }})<br>
                {{ realcomment.content }}
                </td>
                <td>            </td>
                <td>{{ realcomment.auther.username }}</td>
                <td>    </td>
                <td>{{ realcomment.createtime }}</td>
                <td>    </td>
                <td><span><a href="javascript:void(0);" onClick="deleteConfirm('{{ realcomment.id }}')">删除</a></span>
                </tr>
            {% endfor %}
	{% endfor %}
{% else %}
	<p>No comments</p>
{% endif %}
</table>
</div>
<script>
function deleteConfirm(id)
{
    var commentid = id;
    var url_mask = "{% url 'blogs:deleteComment' 'tmpId' %}".replace('tmpId',commentid);
    if(confirm("确认删除该评论吗?"))
    {
        location.href = url_mask;
    }
}
</script>
{% endblock %}

这里要注意的是我们要显示所有博客下的所有评论,因此我们使用了一个二重循环来查找。该页面的view函数如下:
  1. # blogs/views.py  
# blogs/views.py
  1. # ...  
  2. def commentmanage(request):  
  3.     blogList = Blog.objects.filter(auther=request.session['username'])  
  4.     commentList = []  
  5.     for blog in blogList:  
  6.         commentList.append(Comment.objects.filter(attachedblog=blog))  
  7.     return render(request,'blogs/commentmanage.html',{'commentList':commentList})  
  8.   
  9.   
  10. def deletecomment(request,commentId):  
  11.     comment = Comment.objects.get(id=commentId)  
  12.     attachedBlog = comment.attachedblog  
  13.     if attachedBlog.auther.username == request.session['username']:  
  14.         comment.delete()  
  15.         attachedBlog.commentcount -= 1  
  16.         attachedBlog.save()  
  17.     else:  
  18.         return render(request, 'blogs/failedoperation.html')  
  19.     return HttpResponseRedirect(reverse('blogs:commentmanage'))  
# ...
def commentmanage(request):
    blogList = Blog.objects.filter(auther=request.session['username'])
    commentList = []
    for blog in blogList:
        commentList.append(Comment.objects.filter(attachedblog=blog))
    return render(request,'blogs/commentmanage.html',{'commentList':commentList})


def deletecomment(request,commentId):
    comment = Comment.objects.get(id=commentId)
    attachedBlog = comment.attachedblog
    if attachedBlog.auther.username == request.session['username']:
        comment.delete()
        attachedBlog.commentcount -= 1
        attachedBlog.save()
    else:
        return render(request, 'blogs/failedoperation.html')
    return HttpResponseRedirect(reverse('blogs:commentmanage'))
  1. # ...  
# ...
在commentmanage函数里,我们首先需要用username拿到该用户所有的blog,随后再根据每个blog去获取其下所有的comment。此时,commentList的元素为QuerySet对象,因此在前端需要二重循环来显示所有的评论。

deletecomment相对简单,基本与deleteblog函数相同,要注意的是在删除评论后要将对应博客的commentcount-1。

至于draftmanage.html,该页面与blogmanage.html相同,只不过在view函数中获取的是该用户所有draft=True的博客:

  1. # blogs/views.py  
  2. # ...  
  3. def draftmanage(request):  
  4.     blogList = Blog.objects.filter(auther=request.session['username']).filter(draft=True)  
  5.     return render(request, 'blogs/draftmanage.html', {'blogList': blogList})  
  6. # ...  
# blogs/views.py
# ...
def draftmanage(request):
    blogList = Blog.objects.filter(auther=request.session['username']).filter(draft=True)
    return render(request, 'blogs/draftmanage.html', {'blogList': blogList})
# ...
而articleList.html页面与userindex.html相同,这里就不再赘述。

最后是以上页面的url配置:

  1. # blogs/urls.py  
  2. urlpatterns = [  
  3. # ...  
  4.     # blog manage  
  5.     url(r'^articleList/$',views.articlelist,name='articlelist'),  
  6.     url(r'^blogmanage$',views.blogmanage,name='blogmanage'),  
  7.     url(r'^deleteblog/(?P<blogId>.*)$',views.deleteblog,name='deleteBlog'),  
  8.     url(r'^editblog/(?P<blogId>.*)$',views.editblog,name='editBlog'),  
  9.     url(r'^commentmanage$',views.commentmanage,name='commentmanage'),  
  10.     url(r'^deletecomment/(?P<commentId>.*)$',views.deletecomment,name='deleteComment'),  
  11.     url(r'^draftmanage$',views.draftmanage,name='draftmanage')  
  12.   
  13. ]  
# blogs/urls.py
urlpatterns = [
# ...
    # blog manage
    url(r'^articleList/$',views.articlelist,name='articlelist'),
    url(r'^blogmanage$',views.blogmanage,name='blogmanage'),
    url(r'^deleteblog/(?P<blogId>.*)$',views.deleteblog,name='deleteBlog'),
    url(r'^editblog/(?P<blogId>.*)$',views.editblog,name='editBlog'),
    url(r'^commentmanage$',views.commentmanage,name='commentmanage'),
    url(r'^deletecomment/(?P<commentId>.*)$',views.deletecomment,name='deleteComment'),
    url(r'^draftmanage$',views.draftmanage,name='draftmanage')

]

这篇博文介绍了Users App和Blogs App的相关管理功能,篇幅比较长,主要是不想把Blogs App的管理部分拆成两部分来写,这样不利于程序的连贯性。至此,我们的博客又添加了较为完备的博客管理功能,支持博主对博客进行编辑、删除以及管理评论等操作。在后续的博客中,将继续为大家带来学习Django的心得以及博客的新功能,希望大家继续关注~
原文地址:https://www.cnblogs.com/xiaoyaojinzhazhadehangcheng/p/8360490.html