數(shù)據(jù)庫(kù)的配置
現(xiàn)在終于可以進(jìn)入后端的開發(fā)了杉允。不過(guò)在開發(fā)其他功能之前,首先還是要配置好數(shù)據(jù)庫(kù)席里。
數(shù)據(jù)庫(kù)方面叔磷,我使用的是自帶的SQLite數(shù)據(jù)庫(kù),因?yàn)槭褂闷饋?lái)比較方便奖磁,而且也有與之對(duì)應(yīng)的自帶的數(shù)據(jù)庫(kù)管理系統(tǒng)改基。
因?yàn)橹挥袃蓮埍恚?code>models.py中只有兩個(gè)類:
models.py(未完成咖为?)
from django.db import models
import time
# Create your models here.
# 用戶寥裂,其實(shí)只有博主一個(gè)人
class User(models.Model):
username = models.CharField(max_length=150)
password = models.CharField(max_length=150)
# 文章嵌洼,有標(biāo)題、內(nèi)容和發(fā)表時(shí)間三個(gè)屬性
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.CharField(max_length=5000)
date = models.DateTimeField('date', default=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
編寫完成后創(chuàng)建管理員用戶:
python manage.py createsuperuser
然后執(zhí)行遷移命令封恰,初始化數(shù)據(jù)庫(kù):
python manage.py makemigrations backend
python manage.py sqlmigrate backend 0001
python manage.py migrate
因?yàn)橛脩糁挥胁┲饕粋€(gè)麻养,所以使用命令行來(lái)創(chuàng)建博主用戶。
>>> from backend.models import User
>>> u = User(username="admin", password="admin123456")
>>> u.save()
將User類和Article類都加入admin.py
中诺舔,這樣才能在管理頁(yè)面中看到這兩項(xiàng):
from django.contrib import admin
from .models import User, Article
# Register your models here.
admin.site.register(User)
admin.site.register(Article)
執(zhí)行python manage.py runserver
之后進(jìn)入127.0.0.1:8000/admin
鳖昌,就可以看到后臺(tái)管理頁(yè)面了。
登錄功能的實(shí)現(xiàn)
接下來(lái)首先要實(shí)現(xiàn)登錄功能低飒,才能繼續(xù)開發(fā)其他功能许昨,畢竟很多功能的實(shí)現(xiàn)都需要基于權(quán)限控制。
與PHP留言板項(xiàng)目不同褥赊,這次使用Cookie來(lái)做會(huì)話控制糕档。
登錄的流程是這樣的:前端發(fā)起Ajax請(qǐng)求,將用戶名和密碼發(fā)給后端拌喉,后端經(jīng)過(guò)校驗(yàn)之后返回一個(gè)“狀態(tài)碼”和與之對(duì)應(yīng)的消息給前端,并且設(shè)置Cookie尿背,前端根據(jù)接收到的狀態(tài)碼做相應(yīng)處理端仰。
Django在查找數(shù)據(jù)庫(kù)這方面還是非常簡(jiǎn)單的,有對(duì)應(yīng)的API田藐,并不需要編寫SQL語(yǔ)句荔烧。
后端
views.py(未完成)
from django.shortcuts import render
from django.views.generic import View
from django.http import HttpResponseRedirect, JsonResponse, HttpResponse
from .models import User
# Create your views here.
class Login(View):
def get(self, request):
return HttpResponseRedirect('/login')
def post(self, request):
print(request)
name = request.POST.get('name', None)
pwd = request.POST.get('password', None)
try:
user = User.objects.get(username=name)
if user.password == pwd:
r = {
'status': 0,
'msg': '登錄成功!'
}
response = JsonResponse(r)
response.set_cookie('username', name, expires=60 * 15)
return response
else:
r = {
'status': 1,
'msg': '密碼錯(cuò)誤臀稚!'
}
response = JsonResponse(r)
return response
except Exception as e:
r = {
'status': 2,
'msg': '你不是管理員!'
}
print('username:' + name)
print('password:' + pwd)
print(r)
return JsonResponse(r)
有部分代碼只是測(cè)試用的,完成之后會(huì)刪掉蜓肆。
前端
Login.vue(未完成?)
<!--
登錄組件
TODO:開發(fā)登錄功能
-->
<template>
<div class="container">
<h1 class="display-3">Login</h1>
<hr class="my-1">
<form id="login-form">
<div class="form-group">
<label for="name" class="text-left">Username:</label>
<input type="text" class="form-control" id="name" placeholder="Username" v-model="name">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" placeholder="Password" v-model="password">
</div>
<input type="button" @click="post" class="btn btn-secondary" value="Submit">
</form>
</div>
</template>
<script>
export default {
name: 'Login',
data () {
return {
name: '',
password: ''
}
},
mounted () {
let allCookies = document.cookie
if (allCookies.indexOf('username') !== -1) {
this.$router.push('/manage')
}
},
methods: {
post () {
let data = new URLSearchParams()
data.append('name', this.name)
data.append('password', this.password)
this.axios
.post('/login/check/', data)
.then(function (response) {
console.log(response)
alert(response.data.msg)
if (response.data.status === 0) {
location.href = '/manage'
}
})
.catch(function (error) {
console.log(error)
})
}
}
}
</script>
<style scoped>
.container {
padding-top: 100px;
}
h1 {
padding-bottom: 20px;
}
form {
margin-top: 30px;
}
</style>
這里在mounted()
函數(shù)中做了一個(gè)判斷:如果已經(jīng)有cookie了,那就不需要登錄彼城,直接進(jìn)入管理頁(yè)面诅蝶。其他組件中也會(huì)用到這種判斷。
這里用location.href
來(lái)跳轉(zhuǎn)也是無(wú)奈之舉募壕,因?yàn)槭褂胿ue-router總是出各種各樣的問題调炬,無(wú)奈之下只好換這個(gè)了。
登出功能的實(shí)現(xiàn)
這次的登出功能非常簡(jiǎn)單舱馅,因?yàn)橹皇卿N毀Cookie缰泡,所以都不用麻煩后端,直接使用JavaScript來(lái)銷毀就可以代嗤。銷毀的原理是使Cookie超出有效期棘钞。
借鑒了百度經(jīng)驗(yàn)上的一些代碼,侵刪资溃。
Logout.vue(未完成武翎?)
<!--
登出組件
TODO: 開發(fā)登出功能
-->
<template>
</template>
<script>
export default {
name: 'Logout',
methods: {
},
mounted () {
let oDate=new Date()
oDate.setDate(oDate.getDate() + -1);
document.cookie = 'username' + '=' + 'admin'+';expires='+oDate;
alert('登出成功')
this.$router.push('/')
}
}
</script>
<style scoped>
</style>
權(quán)限控制的實(shí)現(xiàn)
因?yàn)槭鞘褂肅ookie進(jìn)行會(huì)話控制,所以權(quán)限控制也是根據(jù)判斷有無(wú)Cookie來(lái)完成溶锭。只要用一點(diǎn)JavaScript就可以宝恶,并不是很難。
核心代碼如下:
mounted () {
let allCookies = document.cookie
if (allCookies.indexOf('username') === -1) {
this.$router.push('/login')
}
也就是在組件裝載的時(shí)候使用JavaScript判斷Cookie是否存在趴捅,如果不存在垫毙,就使用vue-router進(jìn)行強(qiáng)制跳轉(zhuǎn)。在需要權(quán)限控制的組件里加上這段代碼拱绑,然后稍微改一改變量和跳轉(zhuǎn)的目標(biāo)URL就可以了综芥。