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

发布时间:2019-06-08 21:07:22编辑:auto阅读(1814)

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

关键字