基于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 = titlearticle_obj.markdownContent = markdown_contentarticle_obj.htmlContent = html_contentarticle_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页面的设置,修改,明天预计完成文章在前端页面的展示。