后台管理
后台管理
一、后端
# 展示当前用户所有文章
def backend(request):
"""
后天管理
:param request:
:return:
"""
article_obj_list = models.Article.objects.filter(blog=request.user.blog)
return render(request, 'backend/02backend.html', locals())
# 添加文章过滤敏感词汇
from bs4 import BeautifulSoup
def add_article(request):
"""
后台添加文章
:param request:
:return:
"""
# 选择分类和标签内容
category_obj_list = models.Category.objects.filter(blog=request.user.blog)
tag_obj_list = models.Tag.objects.filter(blog=request.user.blog)
if request.method == 'POST':
# 获取内容
title = request.POST.get('title')
content = request.POST.get('comment')
category = request.POST.get('category')
tag_list = request.POST.getlist('tag')
print(request.POST)
print(tag_list)
# 生成一个对象
soup = BeautifulSoup(content, 'html.parser')
# 获取所有的tag标签名称
soup_list = soup.find_all()
# 取出xxs攻击
for tag in soup_list:
if tag.name == 'script':
# 删除script标签
tag.decompose()
# 截取文章信息
desc = soup.text[0:150]
# 添加文章内容
article_obj = models.Article.objects.create(title=title, desc=desc, content=str(soup), blog=request.user.blog,
category_id=category)
# 绑定标签关系
tag_article_list = []
for tag1 in tag_list:
tag_article_list.append(models.ArticleTag(article=article_obj, tag_id=tag1))
# 批量绑定标签内容, bulk_create效率高
models.ArticleTag.objects.bulk_create(tag_article_list)
return redirect('/backend/')
return render(request, 'backend/03add_article.html', locals())
#添加文章中添加图片
import os
from BBS import settings
def upload_img(request):
"""
//成功时
{
"error" : 0,
"url" : "http://www.example.com/path/to/file.ext"
}
//失败时
{
"error" : 1,
"message" : "错误信息"
}
:param request:
:return:
"""
if request.method == 'POST':
back_dic = {'error': 0, 'message': ''}
file_obj = request.FILES.get('imgFile')
file_dir = os.path.join(settings.BASE_DIR, 'media', 'article_img')
print(file_dir)
if not os.path.isdir(file_dir):
os.mkdir(file_dir)
# 凭借图片保存路径
file_path = os.path.join(file_dir, file_obj.name)
# 保存图片
with open(file_path, 'wb') as f:
for line in file_obj:
f.write(line)
back_dic['url'] = f'/media/article_img/{file_obj.name}/'
print(back_dic)
return JsonResponse(back_dic)
# 修改头像
@login_required
def set_img(request):
username = request.user.username
if request.method == 'POST':
img_obj = request.FILES.get('avatar')
print(img_obj)
# 上传头像,路径则不会包含路径不完整,
# user_obj = models.UserInfo.objects.filter(username=request.user.username).update(avatar=img_obj)
user_obj = models.UserInfo.objects.filter(username=request.user.username).first()
user_obj.avatar = img_obj
user_obj.save()
print(user_obj)
return render(request, '09set_img.html', locals())
二、前端
1.后台数据模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% load static %}
<script src="{% static 'bootstrap/js/jquery.js' %}"></script>
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">{{ request.user.blog.site_title }}</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">文章 <span class="sr-only">(current)</span></a></li>
<li><a href="#">随笔</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">更多 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
{% if request.user.is_authenticated %}
<li><a href="#">{{ request.user.username }}</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">更多操作 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="/set_password/" data-toggle="modal" data-target=".bs-example-modal-lg">修改密码</a>
</li>
<li><a href="#">修改头像</a></li>
<li><a href="/backend/">后台管理</a></li>
<li role="separator" class="divider"></li>
<li><a href="/logout/">注销</a></li>
</ul>
</li>
{% else %}
<li><a href="/register/">注册</a></li>
<li><a href="/login/">登录</a></li>
{% endif %}
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne"
aria-expanded="true" aria-controls="collapseOne">
更多操作
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in" role="tabpanel"
aria-labelledby="headingOne">
<div class="panel-body">
<a href="/add_article/">添加文章</a>
</div>
</div>
<div id="collapseOne" class="panel-collapse collapse in" role="tabpanel"
aria-labelledby="headingOne">
<div class="panel-body">
<a href="">添加随笔</a>
</div>
</div>
<div id="collapseOne" class="panel-collapse collapse in" role="tabpanel"
aria-labelledby="headingOne">
<div class="panel-body">
<a href="">评论设置</a>
</div>
</div>
<div id="collapseOne" class="panel-collapse collapse in" role="tabpanel"
aria-labelledby="headingOne">
<div class="panel-body">
<a href="">其他操作</a>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-10">
<div>
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">文章</a></li>
<li role="presentation"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">随笔</a></li>
<li role="presentation"><a href="#messages" aria-controls="messages" role="tab" data-toggle="tab">评论</a></li>
<li role="presentation"><a href="#settings" aria-controls="settings" role="tab" data-toggle="tab">设置</a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home">
{% block article %}
{% endblock %}
</div>
<div role="tabpanel" class="tab-pane" id="profile">
{% block suibi %}
{% endblock %}
</div>
<div role="tabpanel" class="tab-pane" id="messages">
{% block comment %}
{% endblock %}
</div>
<div role="tabpanel" class="tab-pane" id="settings">
{% block settings %}
{% endblock %}
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
2.个人所有文章展示
{% extends 'backend/backend_base.html'%}
{% block article %}
{# 展示当前用户所有的文章 #}
<table class='table table-striped table-hover'>
<thead>
<tr>
<th>标题</th>
<th>发布时间</th>
<th>评论数</th>
<th>点赞数</th>
<th>操作</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for article in article_list %}
<tr>
<td><a href="/{{ request.user.username }}/article/{{ article.pk }}/">{{ article.title }}</a></td>
<td>{{ article.create_time|date:'Y-m-d' }}</td>
<td>{{ article.comment_num }}</td>
<td>{{ article.up_num }}</td>
<td>
<a href="#">编辑</a>
</td>
<td>
<a href="#">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
3.添加文章
{% extends 'backend/backend_base.html' %}
{% block article %}
<div>
<h2>添加文章</h2>
<form action="" method="post">
{% csrf_token %}
<p>标题</p>
<p>
<input type="text" name="title" class="form-control" id="title">
</p>
<p>
内容(编辑器使用kindeditor)
</p>
<p>
<textarea name="content" id="content" cols="30" rows="10"></textarea>
</p>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">分类</h3>
</div>
<div class="panel-body">
{% for category in category_list %}
<input type="radio" value="{{ category.pk }}" name="category">{{ category.name }}
{% endfor %}
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">标签</h3>
</div>
<div class="panel-body">
{% for tag in tag_list %}
<input type="checkbox" value="{{ tag.pk }}" name="tag">{{ tag.name }}
{% endfor %}
</div>
</div>
<input type="submit" class="btn btn-danger">
</form>
</div>
<script charset="utf-8" src="/static/kindeditor/kindeditor-all-min.js"></script>
<script>
KindEditor.ready(function (K) {
window.editor = K.create('#content', {
width: '100%',
height:'450px',
resizeType:1,
uploadJson : '/upload_img/',
extraFileUploadParams : {
'csrfmiddlewaretoken':'{{ csrf_token }}'
}
});
});
</script>
{% endblock %}
4.修改头像
{% extends 'base.html' %}
{% block content %}
<form action="" method="post" class="form-group" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label for="myfile">头像
<img src="/media/{{ request.user.avatar }}" alt="" width="80" style="margin-left: 10px" id="myimg">
</label>
<input type="file" id="myfile" name="avatar" style="display: none">
</div>
<input type="submit" class="btn btn-success">
</form>
{% endblock %}
{% block js %}
<script>
$('#myfile').change(function () {
// 文件阅读器
//1 产生一个文件阅读器对象
var fileReader = new FileReader();
//2 获取用户上传的文件
var fileObj = $(this)[0].files[0];
//3 让文件阅读器读取该文件
fileReader.readAsDataURL(fileObj); // 这一步是异步 提交完之后直接运行下一行
//4 利用文件阅读器将文件展示出来
fileReader.onload = function () {
$('#myimg').attr('src', fileReader.result)
}
});
</script>
{% endblock %}
在当下的阶段,必将由程序员来主导,甚至比以往更甚。