基于django的个人博客网站建立(二)
程序员文章站
2022-04-03 10:17:12
基于django的个人博客网站建立(二) 前言 今天主要完成后台管理员登录的状态以及关于文章在后台的处理 具体内容 首先接上一次内容,昨天只是完成了一个登录的跳转,其他信息并没有保存到session中,今天先完善一下 在用户登录时,先设置了一下session request.session['is_ ......
基于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的个人博客网站建立(六)
-
基于django的个人博客网站建立(一)
-
基于django的个人博客网站建立(五)
-
基于django的个人博客网站建立(二)
-
今天学了一下午,我就建立了自己第一个云上网站,阿里云的这个课程挺NB的,并且还免费,技能超级实用啊,不但有个人博客、论坛、还有电商网站的建设,今天我就NB哄哄建 microsoft
-
基于django的个人博客网站建立(七)
-
基于django的个人博客网站建立(三)
-
基于django的个人博客网站建立(六)
-
基于django的个人博客网站建立(一)
-
建立了自己第一个云上网站,阿里云的这个课程挺NB的,并且还免费,技能超级实用啊,不但有个人博客、论坛、还有电商网站的建设,今天我就NB哄哄建了一个自己的博客 microsoftwordpress