2019-08-13 Django+Vue.js实现前后端分离的单页面博客系统(5)添加博文功能的实现

昨天一直在想一些事情、解决一些问题所以摸鱼了一天没有开发这个项目,今天想到这个项目还没有做完,于是又回来继续做了。只可惜因为白天忙着参加培训,一天只开发了一个添加博文的功能。

注释写的太少真的是一个非常坏的习惯,一天不写,就有很多代码没有办法一眼就看明白了。而且这种坏习惯对以后的工作也不利。

今天忽然想到既然Django自带了后台管理我还写它干什么,这不是重复造轮子吗???不过既然写了,就写完吧,反正也就是一个删除功能而已。

因为换了ID,所以将前端显示的内容也跟着更新了:

首页

注:这个ID不是我的名字也没什么意义,只是觉得ID应该正常点所以随便取了一个。

添加博文功能的原理

添加博文实际上就是向数据库中插入数据,与注册功能类似。虽然这个项目里并没有注册功能,但是不同数据库的增删改查的原理都是相同的,只是在具体实现方面有些不一样。

Django中用来向数据库中插入数据的是save()函数。

添加博文功能的实现

与前一篇文章中写到的创建博主用户的方法类似,添加博文也采用差不多的代码就可以完成,相比之下也就是多了一个date(发布日期)属性而已。

后端

上次写登录功能用了Class来实现,这次采用函数来实现。其实也没有什么特别的,大体思路都差不多。

功能实现

views.py(部分)

有一部分代码仅做调试用途。

from .models import User, Article

def add(request):
    # 检测请求方法,如果是GET则直接返回原页面,是POST则执行接下来的添加操作
    if request.method == 'POST':
        print(request)
        title = request.POST.get('name')
        content = request.POST.get('content')
        date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        try:
            print(title)
            print(content)
            a = Article(title=title, content=content, date=date)
            a.save()
            print(a.id)
            print(a.title)
            print(a.content)
            r = {
                'status': 0,
                'msg': '添加成功!'
            }
            return JsonResponse(r)
        except Exception as e:
            print(e)
            r = {
                'status': 1,
                'msg': '添加失败!'
            }
            return JsonResponse(r)
    else:
        print(request)
        return HttpResponseRedirect('/add')

路由配置

urls.py(未完成)

添加一个/add/check/指向这个函数。指向一个函数与指向一个类在代码层面上有些不一样:指向一个函数需要加类名views。

from django.contrib import admin
from django.urls import path, re_path
from django.views.generic import TemplateView
from backend.views import Login
from backend import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', TemplateView.as_view(template_name='index.html')),
    path('login/', TemplateView.as_view(template_name='index.html')),
    path('login/check/', Login.as_view(), name='login-check'),
    path('add/check/', views.add, name='add-check'),    #添加这一条
    re_path(r'.*', TemplateView.as_view(template_name='index.html'))
]

前端

使用与登录功能几乎相同的代码,就可以实现这个添加功能。

VueAxios真的很好用

Add.vue(未完成?)

<!--
  添加博文组件
  TODO: 开发添加博文的功能
-->
<template>
  <div class="container">
    <div class="main">
      <h1 class="display-3">Add</h1>

      <hr class="my-1">

      <form class="main-form">
        <label for="name">Title:</label>
        <input type="text" class="form-control" id="name" placeholder="Title" v-model="name">
        <label for="content">Content:</label>
        <textarea class="form-control" id="content" rows="10" placeholder="Content" v-model="content"></textarea>
        <input type="button" class="btn btn-secondary" value="Submit" @click="post">
      </form>

    </div>
  </div>
</template>

<script>
  export default {
    name: 'Add',
    data() {
      return {
        'name': '',
        'content': ''
      }
    },
    mounted () {
      let allCookies = document.cookie
      if (allCookies.indexOf('username') === -1) {
        this.$router.push('/login')
      }
    },
    methods: {
      post() {
        let article = new URLSearchParams()
        article.append('name', this.name)
        article.append('content', this.content)
        this.axios
          .post('/add/check/', article)
          .then(function (response) {
            console.log(response)
            alert(response.data.msg)
            if (response.data.status === 0) {
              location.href = '/'
            }
          })
          .catch(function (error) {
            console.log(error)
          })
      }
    }
  }
</script>

<style scoped>

  .main {
    padding-top: 100px;
  }

  label {
    font-size: 1.5em;
    margin: 15px 0 0 0;
  }

  .main-form {
    margin-top: 20px;
  }

  .btn {
    margin-top: 15px;
  }
</style>

实际效果(内容是我胡乱写的):

编辑
添加成功之后的提示与后端接收到的数据

TODO

最近比较忙所以总是忘了还需要做什么,暂时在这里写一下:

  • 更改Cookie的验证方式以及改变Cookie的文本、将Cookie设置为HTTPOnly。现在这种校验Cookie的方式虽然是简单,但是实在是太不安全了。也不能因为是个人项目、不上线就因为简单而放弃安全性啊。
  • 研究如何从数据库中取出数据并发送给前端,前端如何循环显示(大概是拿到数据之后用v-for循环渲染到页面上吧)。
  • 导航条的按钮根据登陆状态是否显示这个功能需要提上日程了,毕竟直接关系到操作逻辑的合理性以及页面的美观。不出意外应该是用v-if