基于django的个人博客网站建立(二)

前言

网站效果可点击这里访问


今天主要完成后台管理员登录的状态以及关于文章在后台的处理

具体内容

首先接上一次内容,昨天只是完成了一个登录的跳转,其他信息并没有保存到session中,今天先完善一下

在用户登录时,先设置了一下session


request.session['is_login'] = True
request.session['email'] = value_dict['email']
request.session['username'] = obj.userName

然后再建立装饰器来对一些需要登录的请求做限制


def auth(func):
def inner(request, *args, **kwargs):
is_login = request.session.get('is_login')
if is_login:
return func(request, *args, **kwargs)
else:
return redirect('/backend/login')
return inner

接下来就是对文章在后台的管理的添加

首先当然是建表:


class ArticleType(models.Model):
name = models.CharField(max_length=128,unique=True) class Article(models.Model):
title = models.CharField(max_length=128)
markdownContent = models.TextField(default='')
htmlContent = models.TextField()
creationTime = models.DateTimeField(auto_now_add=True) class ArticleToType(models.Model):
article = models.ForeignKey(to=Article,on_delete=models.CASCADE)
type = models.ForeignKey(to=ArticleType,on_delete=models.CASCADE) class Meta:
unique_together = ('article', 'type',)

这里建立了3张表,表示文章与类型,文章内容存了两种,一种是markdown,一种是html格式

然后要完成的是对文章类型的管理,主要是显示文章类型,添加文章类型与删除文章类型

我先把完成的网页放出来:

对于页面的返回的视图函数当然要查询所有类别:


@auth
def article_type(request):
if request.method == 'GET':
all_type = models.ArticleType.objects.all()
return render(request,'backend/article_type.html',{"all_type":all_type})

然后是添加类别:


@auth
def add_article_type(request):
if request.method == 'POST':
addType = request.POST.get('addType')
if addType:
print(addType)
count = models.ArticleType.objects.filter(name=addType).count()
if count:
messages.error(request, '添加的类别已经存在')
else:
models.ArticleType.objects.create(name=addType)
else:
messages.error(request, '添加的类别不能为空')
return redirect('/backend/article_type')

这里使用了django中的message,它和flask中的flash类似,可以用来显示错误信息

然后是删除类别;


@auth
def delete_article_type(request):
if request.method == 'POST':
delete_type_id = request.POST.get('delete_type_id')
if delete_type_id:
obj = models.ArticleType.objects.filter(id=delete_type_id).first()
if obj:
obj.delete()
else:
messages.error(request, '删除的类别不存在')
else:
messages.error(request, '删除的类别不能为空')
return redirect('/backend/article_type')

具体的页面借助了模板,也就不再解释了


{% extends 'backend/base.html' %} {% block link %}
<!-- Bootstrap Markdown --> {% endblock %} {% block content %}
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
文章类别
</h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">我的博客后台</a></li>
<li class="breadcrumb-item active">文章类别</li>
</ol>
</section> <!-- Main content -->
<section class="content"> <div class="row"> <div class="col-lg-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">所有类别</h3>
</div>
<!-- /.box-header -->
<div style="height: auto" class="box-body">
<div class="table-responsive">
<table id="articletypelist" class="table table-hover no-wrap dataTable" data-page-size="10" role="grid" aria-describedby="articletypelist_info">
<thead>
<tr role="row"><th class="sorting_asc" tabindex="0" aria-controls="articletypelist" rowspan="1" colspan="1" aria-sort="ascending" aria-label="No: activate to sort column descending">Id</th><th class="sorting" tabindex="0" aria-controls="articletypelist" rowspan="1" colspan="1" aria-label="Name: activate to sort column ascending">Type</th><th class="sorting" tabindex="0" aria-controls="articletypelist" rowspan="1" colspan="1" aria-label="Action: activate to sort column ascending">Action</th></tr>
</thead>
<tbody> {% for type in all_type %}
<tr role="row" class="odd">
<td class="sorting_1">{{ type.id }}</td> <td>{{ type.name }}</td>
<td>
<form action="/backend/delete_article_type/" method="post">
{% csrf_token %}
<input name="delete_type_id" style="display: none" type="text" value="{{ type.id }}">
<button type="submit" class="btn btn-sm btn-danger-outline" data-toggle="tooltip" data-original-title="Delete"><i class="ti-trash" aria-hidden="true"></i></button>
</form>
</td>
</tr>
{% endfor %}
</tbody> </table>
</div>
</div> </div> <div class="box">
<div class="box-header with-border">
<h3 class="box-title">添加类别</h3>
</div>
<!-- /.box-header -->
<div style="height: auto" class="box-body">
<form method="post" action="/backend/add_article_type/">
<input name="addType" type="text" class="form-control" placeholder="输入类别">
<button type="submit" class="btn btn-info margin-top-10">添加</button>
{% csrf_token %}
</form>
</div>
</div>
<!-- /.box -->
</div> </div> </section>
<!-- /.content -->
</div> {% endblock %} {% block script %}
<script>
$('#article_type').addClass('active') </script> {% endblock %}

接下来就是文章的添加:

这里用的是markdown编辑器,可以预览

在后台先pip安装markdown,用于对markdown到html的转换

页面的视图函数为;


@auth
def write_article(request):
if request.method == 'GET':
all_type = models.ArticleType.objects.all()
return render(request, 'backend/write_article.html',{'all_type':all_type})
if request.method == 'POST':
markdown_content = request.POST.get('content')
html_content = markdown(markdown_content)
type_list = request.POST.getlist('article_type')
type_list = [int(i) for i in type_list]
title = request.POST.get('title')
type_obj_list = []
for i in type_list:
type_obj = models.ArticleType.objects.filter(id=i).first()
type_obj_list.append(type_obj)
if html_content and type and title:
obj = models.Article.objects.create(title=title,markdownContent=markdown_content,htmlContent=html_content) for i in type_obj_list:
models.ArticleToType.objects.create(type=i,article=obj)
return redirect('/backend/write_article')
else:
messages.error('文章或类别或标题不能为空')
return redirect('/backend/write_article')

前端代码为:


{% extends 'backend/base.html' %} {% block link %}
<!-- Bootstrap Markdown -->
<link rel="stylesheet" href="/static/assets/backend/vendor_components/bootstrap-markdown-master/css/bootstrap-markdown.css"> {% endblock %} {% block content %}
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
写文章
</h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">我的博客后台</a></li>
<li class="breadcrumb-item active">写文章</li>
</ol>
</section> <!-- Main content -->
<section class="content"> <div class="row"> <div class="col-lg-12">
<form action="/backend/write_article/" method="post">
<div class="box">
<div class="box-header with-border">
<input name="title" type="text" class="form-control" placeholder="输入标题">
</div>
<!-- /.box-header -->
<div style="height: auto" class="box-body"> <div class="example">
<textarea style="height: 500px" name="content" data-provide="markdown" data-iconlibrary="fa"></textarea> </div> </div>
<!-- /.box-body -->
</div> <div class="box">
<div class="box-header with-border">
<h3 class="box-title">选择类别</h3>
</div>
<!-- /.box-header -->
<div style="height: auto" class="box-body">
<div class="form-group validate">
<h5>选择分类 <span class="text-danger">*</span></h5>
<div class="controls">
{% for type in all_type %}
<fieldset>
<label class="custom-control custom-checkbox">
<input type="checkbox" value="{{ type.id }}" name="article_type" class="custom-control-input" aria-invalid="false"> <span class="custom-control-indicator"></span> <span class="custom-control-description">{{ type.name }}</span> </label>
</fieldset>
{% endfor %} </div> </div>
<button id="submit" type="submit" class="btn btn-info margin-top-10">提交</button>
{% csrf_token %}
</div>
</form>
<!-- /.box -->
</div> </div> </section>
<!-- /.content -->
</div> {% endblock %} {% block script %}
<script>
$('#write_article').addClass('active')
$('#submit').click(function () {
var cbs = document.getElementsByName("article_type");
var checkNum = 0;
for (var i = 0; i < cbs.length; i++) {
if (cbs[i].checked) {
checkNum++;
}
}
if (checkNum == 0) {
alert('至少选择一个类别');
return false;
} }) </script> <!-- Bootstrap markdown -->
<script src="/static/assets/backend/vendor_components/bootstrap-markdown-master/js/bootstrap-markdown.js"></script> <!-- marked-->
<script src="/static/assets/backend/vendor_components/marked/marked.js"></script> <!-- to markdown -->
<script src="/static/assets/backend/vendor_components/to-markdown/to-markdown.js"></script>
{% endblock %}

最后是查看文章,这个和文章分类的类似,用一个表格展示

视图函数为;


@auth
def view_article(request):
if request.method == 'GET':
all_article = models.Article.objects.all().order_by('id').reverse()
return render(request,'backend/view_article.html',{'all_article':all_article})

点击右边的按钮是具体查看文章,也就是可以再次编辑:

点击查看按钮的视图函数为:


@auth
def view_article_detail(request):
if request.method == 'GET':
view_article_id = request.GET.get('view_article_id')
article = models.Article.objects.filter(id = int(view_article_id)).first()
return render(request,'backend/view_article_detail.html',{'article':article})

点击保存按钮的视图函数为:


@auth
def save_article(request):
if request.method == 'POST':
markdown_content = request.POST.get('content')
html_content = markdown(markdown_content)
title = request.POST.get('title')
article_id = request.POST.get('article_id')
article_obj = models.Article.objects.filter(id=int(article_id)).first()
article_obj.title = title
article_obj.markdownContent = markdown_content
article_obj.htmlContent = html_content
article_obj.save()
return redirect('/backend/view_article')

这个页面在前端其实就是把数据库该文章的内容填充进去:


{% extends 'backend/base.html' %} {% block link %}
<!-- Bootstrap Markdown -->
<link rel="stylesheet" href="/static/assets/backend/vendor_components/bootstrap-markdown-master/css/bootstrap-markdown.css"> {% endblock %} {% block content %}
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
修改文章
</h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">我的博客后台</a></li>
<li class="breadcrumb-item active">查看文章</li>
<li class="breadcrumb-item active">修改文章</li>
</ol>
</section> <!-- Main content -->
<section class="content"> <div class="row"> <div class="col-lg-12">
<form action="/backend/save_article/" method="post">
<div class="box">
<div class="box-header with-border">
<input value="{{ article.title }}" name="title" type="text" class="form-control" placeholder="输入标题">
</div>
<!-- /.box-header -->
<div style="height: auto" class="box-body"> <div class="example">
<textarea style="height: 500px" name="content" data-provide="markdown" data-iconlibrary="fa">{{ article.markdownContent }}</textarea>
<input type="text" style="display: none" name="article_id" value="{{ article.id }}">
</div>
<button id="submit" type="submit" class="btn btn-info margin-top-10">保存</button>
{% csrf_token %} </div>
<!-- /.box-body -->
</div> </form>
<!-- /.box -->
</div> </div> </section>
<!-- /.content -->
</div> {% endblock %} {% block script %}
<script>
$('#view_article').addClass('active') </script> <!-- Bootstrap markdown -->
<script src="/static/assets/backend/vendor_components/bootstrap-markdown-master/js/bootstrap-markdown.js"></script> <!-- marked-->
<script src="/static/assets/backend/vendor_components/marked/marked.js"></script> <!-- to markdown -->
<script src="/static/assets/backend/vendor_components/to-markdown/to-markdown.js"></script>
{% endblock %}

总结

这次基本上完成了个人博客文章在后台的管理,其实还是花了不少的时间,很多时间是对html页面的设置,修改,明天预计完成文章在前端页面的展示。

基于django的个人博客网站建立(二)的更多相关文章

  1. 基于django的个人博客网站建立(三)

    基于django的个人博客网站建立(三) 前言 网站效果可点击这里访问 今天主要完成的是文章在页面的显示以及评论,留言 具体内容 首先我希望主页面是显示我的所有文章,于是在主页面的视图函数中返回了所有 ...

  2. 基于django的个人博客网站建立(一)

    基于django的个人博客网站建立(一) 前言 网站效果可点击这里访问 之前基于hexo和github page搭建过一个博客网页,后来由于换了个系统,感觉弄的有点麻烦也就没有再去管它了,最近偶然从网 ...

  3. 基于django的个人博客网站建立(七)

    基于django的个人博客网站建立(七) 前言 网站效果可点击这里访问 这次在原来的基础上添加或修改一些小功能 具体内容 1.代码高亮 在原来的blog-details.html页面添加下面的代码: ...

  4. 基于django的个人博客网站建立(六)

    基于django的个人博客网站建立(六) 前言 今天主要完成的是项目在腾讯云服务器上ubuntu16.04+django+mysql+uwsig+nginx的部署过程网站效果可点击这里访问 主要内容 ...

  5. 基于django的个人博客网站建立(五)

    基于django的个人博客网站建立(五) 前言 网站效果可点击这里访问 之前鸽了两天,今天继续再写点 主要内容 今天加了个展示照片的功能,就叫他生活记录吧 先建表 class Record(model ...

  6. 基于django的个人博客网站建立(四)

    基于django的个人博客网站建立(四) 前言 网站效果可点击这里访问 今天主要添加了留言与评论在后台的管理和主页文章的分页显示,文章类别的具体展示以及之前预留链接的补充 主要内容 其实今天的内容和前 ...

  7. 基于docker搭建wordpress博客网站平台

    WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站.也可以把 WordPress当作一个内容管理系统(CMS)来使用. WordPre ...

  8. 【docker构建】基于docker构建wordpress博客网站平台

    WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站.也可以把 WordPress当作一个内容管理系统(CMS)来使用. WordPre ...

  9. 从零搭建基于golang的个人博客网站

    原文链接 : http://www.bugclosed.com/post/14 从零搭建个人博客网站需要包括云服务器(虚拟主机),域名,程序环境,博客程序等方面.本博客 就是通过这几个环节建立起来的, ...

随机推荐

  1. ThreadPoolExecutor线程池的keepAliveTime

    keepAliveTime含义 看了很多文章觉得都不能把keepAliveTime的意思说的很明白,希望通过自己的理解把keepAliveTime说的明确一些 先引用一句我觉得相对说的比较明白的含义: ...

  2. ubuntu 无法应用原保存的显示器配置

    打开ubuntu之后的开启页面出现: 所选模式均不匹配可能的模式: 为 CRTC 63 尝试模式 CRTC 63:尝试 800x600@60Hz 模式输出在 1366x768@60Hz (通过 0) ...

  3. Entity Framework小知识

    记录在使用EF中使用的技巧,以备查阅. 1.当需要查询一个列总和的时候,如果列是允许NULL或者未查到信息的时候,想要返回的是0 而非NULL时 db.表名.Sum(p=> (decimal?) ...

  4. 日常bug整理--xxtz

    2017-12-12 建SQLite数据库表时,遇到外键关联报错:foreign key mismatch 解决:发现是个粗心问题,关联的外键没有作为主键,原因是关联的外键由INT改为varchar字 ...

  5. Python学习-用户输入和字符串拼接

      用户输入和字符串拼接 #用户输入和字符串拼接username=input("username:")age=int(input("Age:")) #转换整数型 ...

  6. 详细讲解:tp3.2.3生成验证码并进行验证(ajax校验返回及自定义返回)

    TP3.2.3的验证码也是比较经典的小功能,框架对这个小功能的封装还是比较完美的,废话不多说,开始记录 1.总体效果: (1)初始界面 (2)自定义的返回校验效果: (3)ajax的校验返回: 2.代 ...

  7. PHP与MYSQL结合操作——文章发布系统小项目(实现基本增删查改操作)

    php和mysql在一起几十年了,也是一对老夫老妻了,最近正在对他们的爱情故事进行探讨,并做了一个很简单的小东西——文章发布系统,目的是为了实现mysql对文章的基本增删查改操作 前台展示系统有:文章 ...

  8. WORD窗体保护密码清除

    Word 2003破解方法如下:1.用Word打开已设置有密码的“保护文档”(原始DOC文件):2.菜单中选择“文件”→“另存为Web页”,保存为HTML文件然后关闭Word:3.用文本编辑器(如:记 ...

  9. cesium加载shp格式数据

    方法一: shp格式转换为GeoJson格式并加载 首先注意shp的坐标系,要转换为WGS84,使用arcgis或QGIS 工具:http://mapshaper.org/: 注意:export时,输 ...

  10. IOS 控件器的创建方式(ViewController)

    ● 控制器常见的创建方式有以下几种 ➢ 通过storyboard创建 ➢ 直接创建 NJViewController *nj = [[NJViewController alloc] init]; ➢ ...