后台管理頁面
在個人主站 頁面中我們設計有管理按鈕,當我們點擊管理按鈕時,應該能進入后台管理自己的文章(注意:這里進入的應該是當前登錄人的后台,而不是該站點的后台)
首先設計url
from blog import views
urlpatterns = [
# 文章詳細頁的點贊url
url(r'digg/$', views.digg),
# 評論
url(r'comment/$', views.comment),
# 后台管理
url(r'^(?P<username>\w+)/backend/$', views.backend),
url(r'^(?P<username>\w+)/backend_add_article/$', views.backend_add_article),
# 個人站點的url
url(r'^(?P<username>\w+)/$', views.home_site),
url(r'^(?P<username>\w+)/(?P<condition>cate|tag|date)/(?P<params>.+)/$', views.home_site),
url(r'^(?P<username>\w+)/articles/(?P<article_id>\d+)\.html/$', views.article_detail),
]
視圖函數
def backend(request, username):
article_list = models.Article.objects.filter(user__username=username)
return render(request, "blog/backend_index.html", locals())
前端頁面
{% load static %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'css/backend_index.css' %}">
<script src="{% static 'jquery-3.2.1.min.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
<title>后台管理</title>
</head>
<body>
<div class="header">
<div class="title">{{ username }}</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<ul class="list-group">
<li class="list-group-item"><a href="/blog/{{ request.user.username }}/backend_add_article">添加文章</a></li>
<li class="list-group-item">分類管理</li>
<li class="list-group-item">標簽操作</li>
</ul>
</div>
<div class="col-md-9">
<div class="con">
<table class="table table-stripped table-hover">
<thead>
<tr>
<th>文章標題</th>
<th>操作</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for article in article_list %}
<tr>
<td>{{ article.title }}</td>
<td><a href="">編輯</a></td>
<td><a href="">刪除</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
css式樣
*{
margin: 0;
padding: 0;
}
.header{
height: 55px;
width: 100%;
background-color: #5e5e5e;
line-height: 55px;
}
.header .title{
font-size: 24px;
font-weight: 200;
color: white;
margin-left: 20px;
}
富文本編輯器
點擊添加文章后我們跳轉到一個新的頁面進行文章編輯,參照博客園,我們可以看到編輯時有很多功能,這里我們使用富文本編輯器(kindeditor)

先下載編輯器,再將文件夾放到static目錄中引用
具體可參看官網http://kindeditor.net/demo.php
前端頁面
{% load static %}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'css/backend_index.css' %}">
<script src="{% static 'jquery-3.2.1.min.js' %}"></script>
<script src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
<title>后台管理</title>
</head>
<body>
<div class="header">
<div class="title">{{ username }}</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<ul class="list-group">
<li class="list-group-item"><a href="/blog/{{ request.user.username }}/backend_add_article">添加文章</a></li>
<li class="list-group-item">分類管理</li>
<li class="list-group-item">標簽操作</li>
</ul>
</div>
<div class="col-md-9">
<form action="" method="post">
<div class="title">
<label for="">標題:</label>
<p><input type="text" name="title"></p>
</div>
<div class="con">
<label for="article_area">內容:(Kindeditor編輯器,支持拖放/粘貼上傳圖片)</label>
<p><textarea name="content" id="article_area" cols="60" rows="10"></textarea></p>
</div>
<p><input type="submit" value="提交" class="btn btn-default"></p>
{% csrf_token %}
</form>
</div>
</div>
</div>
<script charset="utf-8" src="/static/kindeditor/kindeditor-all.js"></script>
<script>
KindEditor.ready(function(K) {
window.editor = K.create('#article_area',{
width:'600px',
height:'600px',
items:[
'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste',
'justifycenter', 'justifyright',
'outdent', 'subscript',
'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/',
'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage',
'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak',
'anchor', 'link', 'unlink', '|', 'about'
],
resizeType:0,
uploadJson:"/upload_file/",
extraFileUploadParams:{"csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()},
filePostName:"upload_img"
});
});
</script>
</body>
</html>
這里可以看到富文本編輯器是配合textarea標簽使用的,編輯器使用時有很多參數可以設計(具體見官網)
這里我們需要注意的是uploadJson參數,這是向服務器傳圖片等文件時需要設置的,一旦點擊了添加圖片的功能,就會向該選項后的url發送請求,該請求是post請求
由於發送post請求需要csrf_token的數據,這里我們使用extraFileUploadParams參數,該參數可以讓我們在發送請求時附帶一些參數,發送到后端后,后端通過request.FILES可以取到發送的圖片,這個值是一個鍵值對
此時使用filePostName參數可以設置鍵為什么,而值則為對應的圖片對象
后端接收圖片的視圖函數
def upload_file(request):
# 保存上傳圖片到指定路徑
obj = request.FILES.get("upload_img")
from BlogYuan import settings
import os
path = os.path.join(settings.MEDIA_ROOT, "article_img", obj.name)
with open(path, "wb") as f_write:
for chunk in obj.chunks():
f_write.write(chunk)
# 給文本編輯器返回json字符串
upload_response = {
"error": 0, # 0表示沒錯
"url": "/media/article_img/%s" % (obj.name)
}
return HttpResponse(json.dumps(upload_response))
接收到圖片並保存在服務端的media目錄中后,我們需要向前端進行響應,這里需要注意,響應的json字符串中,error字段表示是否有錯誤,0表示沒有錯誤
url字段表示圖片的路徑,只有將他發給前端,前端頁面才能預覽到圖片
過濾文章內容
當我們提交了我們的文章后,后台接收到文章內容后,不能直接存到數據庫,需要對文章內容進行過濾,去掉一些非法內容
這里我們使用到了BS(BeautifulSoup)模塊,可以對文章中的標簽等內容進行搜索、查詢、修改等
BS模塊具體使用http://www.cnblogs.com/yuanchenqi/articles/7617280.html
官方文檔http://beautifulsoup.readthedocs.io/zh_CN/latest/
視圖函數
def backend_add_article(request, username):
if request.method == "POST":
content = request.POST.get("content")
title = request.POST.get("title")
# 用BS模塊過濾content
valid_tags_attrs_list = {
"div": ["id", "class", "style"],
"img": ["src", "width", "height"],
"a": ["href"],
"p": []
}
from bs4 import BeautifulSoup
soup = BeautifulSoup(content, "html.parser")
tags_list = soup.find_all()
for tag in tags_list:
if tag.name not in valid_tags_attrs_list:
tag.decompose()
else:
for attr in tag.attrs:
if attr not in valid_tags_attrs_list[tag.name]:
del tag[attr]
return render(request, "blog/backend_add_article.html")
這里我們接收到文章的標題和內容,然后自己定義了一個有效的標簽字典,里面含有有效的標簽屬性
然后通過BS模塊拿到文章內容的所有標簽,對這些標簽進行篩選,刪掉無效的標簽和無效的標簽屬性
成功后可以將數據存入數據庫,再跳轉到成功頁面(上面的代碼中未寫)

